Merge "InputSettings: Add mouse acceleration setting" into main
diff --git a/core/api/current.txt b/core/api/current.txt
index 7c56a58..d0b3a51 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -20781,11 +20781,11 @@
     method @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public void registerDisplayListener(@NonNull java.util.concurrent.Executor, long, @NonNull android.hardware.display.DisplayManager.DisplayListener);
     method public void unregisterDisplayListener(android.hardware.display.DisplayManager.DisplayListener);
     field public static final String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
-    field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_FLAG_DISPLAY_ADDED = 1L; // 0x1L
-    field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_FLAG_DISPLAY_CHANGED = 4L; // 0x4L
-    field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_FLAG_DISPLAY_REFRESH_RATE = 8L; // 0x8L
-    field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_FLAG_DISPLAY_REMOVED = 2L; // 0x2L
-    field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_FLAG_DISPLAY_STATE = 16L; // 0x10L
+    field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_TYPE_DISPLAY_ADDED = 1L; // 0x1L
+    field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_TYPE_DISPLAY_CHANGED = 4L; // 0x4L
+    field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_TYPE_DISPLAY_REFRESH_RATE = 8L; // 0x8L
+    field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_TYPE_DISPLAY_REMOVED = 2L; // 0x2L
+    field @FlaggedApi("com.android.server.display.feature.flags.display_listener_performance_improvements") public static final long EVENT_TYPE_DISPLAY_STATE = 16L; // 0x10L
     field public static final int MATCH_CONTENT_FRAMERATE_ALWAYS = 2; // 0x2
     field public static final int MATCH_CONTENT_FRAMERATE_NEVER = 0; // 0x0
     field public static final int MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY = 1; // 0x1
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index ff5b2bd..e724ab8 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -5157,18 +5157,18 @@
   }
 
   @FlaggedApi("android.chre.flags.offload_api") public final class HubMessage implements android.os.Parcelable {
-    ctor public HubMessage(int, @NonNull byte[]);
-    ctor public HubMessage(int, @NonNull byte[], @NonNull android.hardware.contexthub.HubMessage.DeliveryParams);
     method public int describeContents();
     method @NonNull public byte[] getMessageBody();
     method public int getMessageType();
+    method public boolean isResponseRequired();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.hardware.contexthub.HubMessage> CREATOR;
   }
 
-  public static class HubMessage.DeliveryParams {
-    ctor public HubMessage.DeliveryParams(boolean);
-    method public boolean isResponseRequired();
+  public static final class HubMessage.Builder {
+    ctor public HubMessage.Builder(int, @NonNull byte[]);
+    method @NonNull public android.hardware.contexthub.HubMessage build();
+    method @NonNull public android.hardware.contexthub.HubMessage.Builder setResponseRequired(boolean);
   }
 
   @FlaggedApi("android.chre.flags.offload_api") public final class HubServiceInfo implements android.os.Parcelable {
@@ -12676,21 +12676,27 @@
 package android.security.advancedprotection {
 
   @FlaggedApi("android.security.aapm_api") public final class AdvancedProtectionFeature implements android.os.Parcelable {
-    ctor public AdvancedProtectionFeature(int);
+    ctor public AdvancedProtectionFeature(@NonNull String);
     method public int describeContents();
-    method public int getId();
+    method @NonNull public String getId();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.security.advancedprotection.AdvancedProtectionFeature> CREATOR;
   }
 
   @FlaggedApi("android.security.aapm_api") public final class AdvancedProtectionManager {
+    method @NonNull public android.content.Intent createSupportIntent(@NonNull String, @Nullable String);
     method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE) public java.util.List<android.security.advancedprotection.AdvancedProtectionFeature> getAdvancedProtectionFeatures();
     method @RequiresPermission(android.Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE) public void setAdvancedProtectionEnabled(boolean);
-    field public static final int FEATURE_ID_DISALLOW_CELLULAR_2G = 0; // 0x0
-    field public static final int FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES = 1; // 0x1
-    field public static final int FEATURE_ID_DISALLOW_USB = 2; // 0x2
-    field public static final int FEATURE_ID_DISALLOW_WEP = 3; // 0x3
-    field public static final int FEATURE_ID_ENABLE_MTE = 4; // 0x4
+    field @FlaggedApi("android.security.aapm_api") public static final String ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG = "android.security.advancedprotection.action.SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG";
+    field public static final String EXTRA_SUPPORT_DIALOG_FEATURE = "android.security.advancedprotection.extra.SUPPORT_DIALOG_FEATURE";
+    field public static final String EXTRA_SUPPORT_DIALOG_TYPE = "android.security.advancedprotection.extra.SUPPORT_DIALOG_TYPE";
+    field public static final String FEATURE_ID_DISALLOW_CELLULAR_2G = "android.security.advancedprotection.feature_disallow_2g";
+    field public static final String FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES = "android.security.advancedprotection.feature_disallow_install_unknown_sources";
+    field public static final String FEATURE_ID_DISALLOW_USB = "android.security.advancedprotection.feature_disallow_usb";
+    field public static final String FEATURE_ID_DISALLOW_WEP = "android.security.advancedprotection.feature_disallow_wep";
+    field public static final String FEATURE_ID_ENABLE_MTE = "android.security.advancedprotection.feature_enable_mte";
+    field public static final String SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION = "android.security.advancedprotection.type_blocked_interaction";
+    field public static final String SUPPORT_DIALOG_TYPE_DISABLED_SETTING = "android.security.advancedprotection.type_disabled_setting";
   }
 
 }
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 5171e68..ed8042d 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1677,6 +1677,7 @@
 
   @FlaggedApi("android.hardware.devicestate.feature.flags.device_state_property_api") public final class DeviceState {
     ctor public DeviceState(@NonNull android.hardware.devicestate.DeviceState.Configuration);
+    field @FlaggedApi("android.hardware.devicestate.feature.flags.device_state_rdm_v2") public static final int PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT = 1001; // 0x3e9
     field public static final int PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST = 8; // 0x8
   }
 
@@ -4135,6 +4136,7 @@
     method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public boolean isInputMethodPickerShown();
     method @NonNull @RequiresPermission(value=android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional=true) public boolean isStylusHandwritingAvailableAsUser(@NonNull android.os.UserHandle);
     method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public void setStylusWindowIdleTimeoutForTest(long);
+    method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public boolean shouldShowImeSwitcherButtonForTest();
     field public static final long CLEAR_SHOW_FORCED_FLAG_WHEN_LEAVING = 214016041L; // 0xcc1a029L
   }
 
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index 4db3727..0e45902 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -38,6 +38,7 @@
 import android.os.PowerExemptionManager;
 import android.os.PowerExemptionManager.ReasonCode;
 import android.os.PowerExemptionManager.TempAllowListType;
+import android.os.Process;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -76,6 +77,7 @@
             FLAG_IS_ALARM_BROADCAST,
             FLAG_SHARE_IDENTITY,
             FLAG_INTERACTIVE,
+            FLAG_DEBUG_LOG,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Flags {}
@@ -86,6 +88,7 @@
     private static final int FLAG_IS_ALARM_BROADCAST = 1 << 3;
     private static final int FLAG_SHARE_IDENTITY = 1 << 4;
     private static final int FLAG_INTERACTIVE = 1 << 5;
+    private static final int FLAG_DEBUG_LOG = 1 << 6;
 
     /**
      * Change ID which is invalid.
@@ -1082,6 +1085,34 @@
     }
 
     /**
+     * If enabled, additional debug messages for broadcast delivery will be logged.
+     *
+     * <p> This will only take effect when used by {@link Process#SHELL_UID}
+     * or {@link Process#ROOT_UID} or by apps under instrumentation.
+     *
+     * @hide
+     */
+    @NonNull
+    public BroadcastOptions setDebugLogEnabled(boolean enabled) {
+        if (enabled) {
+            mFlags |= FLAG_DEBUG_LOG;
+        } else {
+            mFlags &= ~FLAG_DEBUG_LOG;
+        }
+        return this;
+    }
+
+    /**
+     * @return if additional debug messages for broadcast delivery are enabled.
+     *
+     * @see #setDebugLogEnabled(boolean)
+     * @hide
+     */
+    public boolean isDebugLogEnabled() {
+        return (mFlags & FLAG_DEBUG_LOG) != 0;
+    }
+
+    /**
      * Returns the created options as a Bundle, which can be passed to
      * {@link android.content.Context#sendBroadcast(android.content.Intent)
      * Context.sendBroadcast(Intent)} and related methods.
diff --git a/core/java/android/app/IApplicationStartInfoCompleteListener.aidl b/core/java/android/app/IApplicationStartInfoCompleteListener.aidl
index 0f0d919..f7e5f18 100644
--- a/core/java/android/app/IApplicationStartInfoCompleteListener.aidl
+++ b/core/java/android/app/IApplicationStartInfoCompleteListener.aidl
@@ -25,6 +25,6 @@
  *
  * @hide
  */
-interface IApplicationStartInfoCompleteListener {
+oneway interface IApplicationStartInfoCompleteListener {
     void onApplicationStartInfoComplete(in ApplicationStartInfo applicationStartInfo);
 }
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index a6c1a57..0451ac0 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -270,6 +270,6 @@
 
     int[] getAllowedAdjustmentKeyTypes();
     void setAssistantAdjustmentKeyTypeState(int type, boolean enabled);
-    String[] getTypeAdjustmentDeniedPackages();
-    void setTypeAdjustmentForPackageState(String pkg, boolean enabled);
+    int[] getAllowedAdjustmentKeyTypesForPackage(String pkg);
+    void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, int type, boolean enabled);
 }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index eeb1ebb..8ffea23 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6453,6 +6453,13 @@
             big.setColorStateList(R.id.snooze_button, "setImageTintList", actionColor);
             big.setColorStateList(R.id.bubble_button, "setImageTintList", actionColor);
 
+            if (Flags.notificationsRedesignTemplates()) {
+                int margin = getContentMarginTop(mContext,
+                        R.dimen.notification_2025_content_margin_top);
+                big.setViewLayoutMargin(R.id.notification_main_column, RemoteViews.MARGIN_TOP,
+                        margin, TypedValue.COMPLEX_UNIT_PX);
+            }
+
             boolean validRemoteInput = false;
 
             // In the UI, contextual actions appear separately from the standard actions, so we
@@ -6549,6 +6556,30 @@
             return big;
         }
 
+        /**
+         * Calculate the top margin for the content in px, to allow enough space for the top line
+         * above, using the given resource ID for the desired spacing.
+         *
+         * @hide
+         */
+        public static int getContentMarginTop(Context context, @DimenRes int spacingRes) {
+            final Resources resources = context.getResources();
+            // The margin above the text, at the top of the notification (originally in dp)
+            int notifMargin = resources.getDimensionPixelSize(R.dimen.notification_2025_margin);
+            // Spacing between the text lines, scaling with the font size (originally in sp)
+            int spacing = resources.getDimensionPixelSize(spacingRes);
+
+            // Size of the text in the notification top line (originally in sp)
+            int[] textSizeAttr = new int[] { android.R.attr.textSize };
+            TypedArray typedArray = context.obtainStyledAttributes(
+                    R.style.TextAppearance_DeviceDefault_Notification_Info, textSizeAttr);
+            int textSize = typedArray.getDimensionPixelSize(0 /* index */, -1 /* default */);
+            typedArray.recycle();
+
+            // Adding up all the values as pixels
+            return notifMargin + spacing + textSize;
+        }
+
         private boolean hasValidRemoteInput(Action action) {
             if (TextUtils.isEmpty(action.title) || action.actionIntent == null) {
                 // Weird actions
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 2da7147..08bd854 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -768,6 +768,10 @@
         INotificationManager service = service();
         String sender = mContext.getPackageName();
 
+        if (discardNotify(mContext.getUser(), targetPackage, tag, id, notification)) {
+            return;
+        }
+
         try {
             if (localLOGV) Log.v(TAG, sender + ": notify(" + id + ", " + notification + ")");
             service.enqueueNotificationWithTag(targetPackage, sender, tag, id,
@@ -918,6 +922,10 @@
      * @param id An identifier for this notification.
      */
     public void cancelAsPackage(@NonNull String targetPackage, @Nullable String tag, int id) {
+        if (discardCancel(mContext.getUser(), targetPackage, tag, id)) {
+            return;
+        }
+
         INotificationManager service = service();
         try {
             service.cancelNotificationWithTag(targetPackage, mContext.getOpPackageName(),
@@ -981,16 +989,20 @@
      */
     public void cancelAll()
     {
+        String pkg = mContext.getPackageName();
+        UserHandle user = mContext.getUser();
+
         if (Flags.nmBinderPerfThrottleNotify()) {
             synchronized (mThrottleLock) {
                 for (NotificationKey key : mKnownNotifications.snapshot().keySet()) {
-                    mKnownNotifications.put(key, KNOWN_STATUS_CANCELLED);
+                    if (key.pkg.equals(pkg) && key.user.equals(user)) {
+                        mKnownNotifications.put(key, KNOWN_STATUS_CANCELLED);
+                    }
                 }
             }
         }
 
         INotificationManager service = service();
-        String pkg = mContext.getPackageName();
         if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
         try {
             service.cancelAllNotifications(pkg, mContext.getUserId());
@@ -1014,7 +1026,7 @@
     public void setNotificationDelegate(@Nullable String delegate) {
         INotificationManager service = service();
         String pkg = mContext.getPackageName();
-        if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
+        if (localLOGV) Log.v(TAG, pkg + ": setNotificationDelegate()");
         try {
             service.setNotificationDelegate(pkg, delegate);
         } catch (RemoteException e) {
@@ -1974,10 +1986,12 @@
      * @hide
      */
     @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
-    public void setTypeAdjustmentForPackageState(@NonNull String pkg, boolean enabled) {
+    public void setAssistantAdjustmentKeyTypeStateForPackage(@NonNull String pkg,
+                                                             @Adjustment.Types int type,
+                                                             boolean enabled) {
         INotificationManager service = service();
         try {
-            service.setTypeAdjustmentForPackageState(pkg, enabled);
+            service.setAssistantAdjustmentKeyTypeStateForPackage(pkg, type, enabled);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 39c27a1..84d6741 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -17430,12 +17430,17 @@
     }
 
     /**
-     * Removes a manged profile from the device only when called from a managed profile's context
+     * Removes a managed profile from the device.
      *
-     * @param user UserHandle of the profile to be removed
+     * <p>
+     * Removes the managed profile which is specified by the context user
+     * ({@code Context.createContextAsUser()}).
+     * <p>
+     *
      * @return {@code true} when removal of managed profile was successful, {@code false} when
-     * removal was unsuccessful or throws IllegalArgumentException when provided user was not a
+     * removal was unsuccessful or throws IllegalArgumentException when specified user was not a
      * managed profile
+     *
      * @hide
      */
     @SystemApi
diff --git a/core/java/android/app/appfunctions/SafeOneTimeExecuteAppFunctionCallback.java b/core/java/android/app/appfunctions/SafeOneTimeExecuteAppFunctionCallback.java
index e527de2..88001fc 100644
--- a/core/java/android/app/appfunctions/SafeOneTimeExecuteAppFunctionCallback.java
+++ b/core/java/android/app/appfunctions/SafeOneTimeExecuteAppFunctionCallback.java
@@ -19,7 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.RemoteException;
-import android.os.SystemClock;
 import android.util.Log;
 
 import java.util.Objects;
@@ -40,8 +39,7 @@
 
     @NonNull private final IExecuteAppFunctionCallback mCallback;
 
-    @Nullable
-    private final CompletionCallback mCompletionCallback;
+    @Nullable private final CompletionCallback mCompletionCallback;
 
     private final AtomicLong mExecutionStartTimeAfterBindMillis = new AtomicLong();
 
@@ -49,7 +47,8 @@
         this(callback, /* completionCallback= */ null);
     }
 
-    public SafeOneTimeExecuteAppFunctionCallback(@NonNull IExecuteAppFunctionCallback callback,
+    public SafeOneTimeExecuteAppFunctionCallback(
+            @NonNull IExecuteAppFunctionCallback callback,
             @Nullable CompletionCallback completionCallback) {
         mCallback = Objects.requireNonNull(callback);
         mCompletionCallback = completionCallback;
@@ -64,8 +63,8 @@
         try {
             mCallback.onSuccess(result);
             if (mCompletionCallback != null) {
-                mCompletionCallback.finalizeOnSuccess(result,
-                        mExecutionStartTimeAfterBindMillis.get());
+                mCompletionCallback.finalizeOnSuccess(
+                        result, mExecutionStartTimeAfterBindMillis.get());
             }
         } catch (RemoteException ex) {
             // Failed to notify the other end. Ignore.
@@ -82,8 +81,8 @@
         try {
             mCallback.onError(error);
             if (mCompletionCallback != null) {
-                mCompletionCallback.finalizeOnError(error,
-                        mExecutionStartTimeAfterBindMillis.get());
+                mCompletionCallback.finalizeOnError(
+                        error, mExecutionStartTimeAfterBindMillis.get());
             }
         } catch (RemoteException ex) {
             // Failed to notify the other end. Ignore.
@@ -103,9 +102,10 @@
      * Sets the execution start time of the request. Used to calculate the overhead latency of
      * requests.
      */
-    public void setExecutionStartTimeMillis() {
-        if (!mExecutionStartTimeAfterBindMillis.compareAndSet(0, SystemClock.elapsedRealtime())) {
-            Log.w(TAG, "Ignore subsequent calls to setExecutionStartTimeMillis()");
+    public void setExecutionStartTimeAfterBindMillis(long executionStartTimeAfterBindMillis) {
+        if (!mExecutionStartTimeAfterBindMillis.compareAndSet(
+                0, executionStartTimeAfterBindMillis)) {
+            Log.w(TAG, "Ignore subsequent calls to setExecutionStartTimeAfterBindMillis()");
         }
     }
 
@@ -115,8 +115,8 @@
      */
     public interface CompletionCallback {
         /** Called after {@link IExecuteAppFunctionCallback#onSuccess}. */
-        void finalizeOnSuccess(@NonNull ExecuteAppFunctionResponse result,
-                long executionStartTimeMillis);
+        void finalizeOnSuccess(
+                @NonNull ExecuteAppFunctionResponse result, long executionStartTimeMillis);
 
         /** Called after {@link IExecuteAppFunctionCallback#onError}. */
         void finalizeOnError(@NonNull AppFunctionException error, long executionStartTimeMillis);
diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl
index 55957bf..7f14925 100644
--- a/core/java/android/content/pm/ILauncherApps.aidl
+++ b/core/java/android/content/pm/ILauncherApps.aidl
@@ -83,8 +83,6 @@
 
     ParceledListSlice getShortcuts(String callingPackage, in ShortcutQueryWrapper query,
             in UserHandle user);
-    void getShortcutsAsync(String callingPackage, in ShortcutQueryWrapper query,
-            in UserHandle user, in AndroidFuture<List<ShortcutInfo>> cb);
     void pinShortcuts(String callingPackage, String packageName, in List<String> shortcutIds,
             in UserHandle user);
     boolean startShortcut(String callingPackage, String packageName, String featureId, String id,
diff --git a/core/java/android/content/pm/IShortcutService.aidl b/core/java/android/content/pm/IShortcutService.aidl
index 86087cb..371f645 100644
--- a/core/java/android/content/pm/IShortcutService.aidl
+++ b/core/java/android/content/pm/IShortcutService.aidl
@@ -21,8 +21,6 @@
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ShortcutInfo;
 
-import com.android.internal.infra.AndroidFuture;
-
 /** {@hide} */
 interface IShortcutService {
 
@@ -38,11 +36,11 @@
 
     boolean updateShortcuts(String packageName, in ParceledListSlice shortcuts, int userId);
 
-    void requestPinShortcut(String packageName, in ShortcutInfo shortcut,
-            in IntentSender resultIntent, int userId, in AndroidFuture<String> ret);
+    boolean requestPinShortcut(String packageName, in ShortcutInfo shortcut,
+            in IntentSender resultIntent, int userId);
 
-    void createShortcutResultIntent(String packageName, in ShortcutInfo shortcut, int userId,
-            in AndroidFuture<Intent> ret);
+    Intent createShortcutResultIntent(String packageName, in ShortcutInfo shortcut,
+            int userId);
 
     void disableShortcuts(String packageName, in List<String> shortcutIds,
             CharSequence disabledMessage, int disabledMessageResId, int userId);
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 26b8356..a0c0f12 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -464,17 +464,6 @@
         public static final int FLAG_GET_KEY_FIELDS_ONLY = 1 << 2;
 
         /**
-         * Includes shortcuts from persistence layer in the search result.
-         *
-         * <p>The caller should make the query on a worker thread since accessing persistence layer
-         * is considered asynchronous.
-         *
-         * @hide
-         */
-        @SystemApi
-        public static final int FLAG_GET_PERSISTED_DATA = 1 << 12;
-
-        /**
          * Populate the persons field in the result. See {@link ShortcutInfo#getPersons()}.
          *
          * <p>The caller must have the system {@code ACCESS_SHORTCUTS} permission.
@@ -485,6 +474,17 @@
         @RequiresPermission(android.Manifest.permission.ACCESS_SHORTCUTS)
         public static final int FLAG_GET_PERSONS_DATA = 1 << 11;
 
+        /**
+         * Includes shortcuts from persistence layer in the search result.
+         *
+         * <p>The caller should make the query on a worker thread since accessing persistence layer
+         * is considered asynchronous.
+         *
+         * @hide
+         */
+        @SystemApi
+        public static final int FLAG_GET_PERSISTED_DATA = 1 << 12;
+
         /** @hide */
         @IntDef(flag = true, prefix = { "FLAG_" }, value = {
                 FLAG_MATCH_DYNAMIC,
@@ -1500,9 +1500,6 @@
             @NonNull UserHandle user) {
         logErrorForInvalidProfileAccess(user);
         try {
-            if ((query.mQueryFlags & ShortcutQuery.FLAG_GET_PERSISTED_DATA) != 0) {
-                return getShortcutsBlocked(query, user);
-            }
             // Note this is the only case we need to update the disabled message for shortcuts
             // that weren't restored.
             // The restore problem messages are only shown by the user, and publishers will never
@@ -1517,22 +1514,6 @@
         }
     }
 
-    private List<ShortcutInfo> getShortcutsBlocked(@NonNull ShortcutQuery query,
-            @NonNull UserHandle user) {
-        logErrorForInvalidProfileAccess(user);
-        final AndroidFuture<List<ShortcutInfo>> future = new AndroidFuture<>();
-        future.thenApply(this::maybeUpdateDisabledMessage);
-        try {
-            mService.getShortcutsAsync(mContext.getPackageName(),
-                            new ShortcutQueryWrapper(query), user, future);
-            return future.get();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        } catch (InterruptedException | ExecutionException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
     /**
      * @hide // No longer used.  Use getShortcuts() instead.  Kept for unit tests.
      */
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index cd62573..d64ef75 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -3617,7 +3617,9 @@
          * automatically fetched and installed when installing an app that wants to use these
          * dependencies.
          *
-         * <p> This feature is enabled by default.
+         * <p> This feature is enabled by default. Note that in the case of a multi-package
+         * installation session, no dependencies will be automatically installed even if this field
+         * is set to true.
          *
          * @param enableAutoInstallDependencies {@code true} to enable auto-installation of missing
          *                                      SDK or static shared library dependencies,
@@ -4574,6 +4576,9 @@
          * Check whether missing SDK or static shared library dependencies should be automatically
          * fetched and installed when installing an app that wants to use these dependencies.
          *
+         * <p> Note that in the case of a multi-package installation session, no dependencies will
+         * be automatically installed even if this method returns true.
+         *
          * @return true if the dependencies will be auto-installed, false otherwise.
          */
         @FlaggedApi(Flags.FLAG_SDK_DEPENDENCY_INSTALLER)
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index 3514914..683f312 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -44,7 +44,6 @@
 import android.os.ServiceManager;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.infra.AndroidFuture;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -598,10 +597,8 @@
     public boolean requestPinShortcut(@NonNull ShortcutInfo shortcut,
             @Nullable IntentSender resultIntent) {
         try {
-            AndroidFuture<String> ret = new AndroidFuture<>();
-            mService.requestPinShortcut(mContext.getPackageName(), shortcut, resultIntent,
-                    injectMyUserId(), ret);
-            return Boolean.parseBoolean(getFutureOrThrow(ret));
+            return mService.requestPinShortcut(mContext.getPackageName(), shortcut, resultIntent,
+                    injectMyUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -626,11 +623,9 @@
      */
     @WorkerThread
     public Intent createShortcutResultIntent(@NonNull ShortcutInfo shortcut) {
-        final AndroidFuture<Intent> ret = new AndroidFuture<>();
         try {
-            mService.createShortcutResultIntent(mContext.getPackageName(),
-                    shortcut, injectMyUserId(), ret);
-            Intent result = getFutureOrThrow(ret);
+            Intent result = mService.createShortcutResultIntent(mContext.getPackageName(),
+                    shortcut, injectMyUserId());
             if (result != null) {
                 result.prepareToEnterProcess(LOCAL_FLAG_FROM_SYSTEM,
                         mContext.getAttributionSource());
@@ -793,21 +788,4 @@
             throw e.rethrowFromSystemServer();
         }
     }
-
-    private static <T> T getFutureOrThrow(@NonNull AndroidFuture<T> future) {
-        try {
-            return future.get();
-        } catch (Throwable e) {
-            if (e instanceof ExecutionException) {
-                e = e.getCause();
-            }
-            if (e instanceof RuntimeException) {
-                throw (RuntimeException) e;
-            }
-            if (e instanceof Error) {
-                throw (Error) e;
-            }
-            throw new RuntimeException(e);
-        }
-    }
 }
diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java
index c811a47..d38b2f0 100644
--- a/core/java/android/content/pm/ShortcutServiceInternal.java
+++ b/core/java/android/content/pm/ShortcutServiceInternal.java
@@ -52,19 +52,6 @@
             @Nullable List<LocusId> locusIds, @Nullable ComponentName componentName,
             @ShortcutQuery.QueryFlags int flags, int userId, int callingPid, int callingUid);
 
-    /**
-     * Retrieves shortcuts asynchronously. Query will go through persistence layer (thus making the
-     * call async) if querying by shortcutIds in a specific package; otherwise it's effectively the
-     * same as calling {@link #getShortcuts}.
-     */
-    public abstract void
-            getShortcutsAsync(int launcherUserId,
-            @NonNull String callingPackage, long changedSince,
-            @Nullable String packageName, @Nullable List<String> shortcutIds,
-            @Nullable List<LocusId> locusIds, @Nullable ComponentName componentName,
-            @ShortcutQuery.QueryFlags int flags, int userId, int callingPid, int callingUid,
-            AndroidFuture<List<ShortcutInfo>> cb);
-
     public abstract boolean
             isPinnedByCaller(int launcherUserId, @NonNull String callingPackage,
             @NonNull String packageName, @NonNull String id, int userId);
@@ -78,14 +65,6 @@
             @NonNull String packageName, @NonNull String shortcutId, int userId,
             int callingPid, int callingUid);
 
-    /**
-     * Retrieves the intents from a specified shortcut asynchronously.
-     */
-    public abstract void createShortcutIntentsAsync(
-            int launcherUserId, @NonNull String callingPackage,
-            @NonNull String packageName, @NonNull String shortcutId, int userId,
-            int callingPid, int callingUid, @NonNull AndroidFuture<Intent[]> cb);
-
     public abstract void addListener(@NonNull ShortcutChangeListener listener);
 
     public abstract void addShortcutChangeCallback(
@@ -108,13 +87,6 @@
             @NonNull String callingPackage,
             @NonNull String packageName, @NonNull String shortcutId, int userId);
 
-    /**
-     * Retrieves a file descriptor from the icon in a specified shortcut asynchronously.
-     */
-    public abstract void getShortcutIconFdAsync(int launcherUserId, @NonNull String callingPackage,
-            @NonNull String packageName, @NonNull String shortcutId, int userId,
-            @NonNull AndroidFuture<ParcelFileDescriptor> cb);
-
     public abstract boolean hasShortcutHostPermission(int launcherUserId,
             @NonNull String callingPackage, int callingPid, int callingUid);
 
@@ -155,14 +127,6 @@
     public abstract String getShortcutIconUri(int launcherUserId, @NonNull String launcherPackage,
             @NonNull String packageName, @NonNull String shortcutId, int userId);
 
-    /**
-     * Retrieves the icon Uri of the shortcut asynchronously, and grants Uri read permission to the
-     * caller.
-     */
-    public abstract void getShortcutIconUriAsync(int launcherUserId,
-            @NonNull String launcherPackage, @NonNull String packageName,
-            @NonNull String shortcutId, int userId, @NonNull AndroidFuture<String> cb);
-
     public abstract boolean isSharingShortcut(int callingUserId, @NonNull String callingPackage,
             @NonNull String packageName, @NonNull String shortcutId, int userId,
             @NonNull IntentFilter filter);
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index f29e2e8..2ad9660 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -211,6 +211,16 @@
 }
 
 flag {
+    name: "place_add_user_dialog_within_activity"
+    namespace: "multiuser"
+    description: "Display dialog within activity to make it traversable by Accessibility"
+    bug: "383034393"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
     name: "property_invalidated_cache_bypass_mismatched_uids"
     namespace: "multiuser"
     description: "Bypass the cache when the process UID does not match the binder UID."
diff --git a/core/java/android/credentials/flags.aconfig b/core/java/android/credentials/flags.aconfig
index 9c811fb..2161e10 100644
--- a/core/java/android/credentials/flags.aconfig
+++ b/core/java/android/credentials/flags.aconfig
@@ -13,6 +13,16 @@
 
 flag {
     namespace: "credential_manager"
+    name: "package_update_fix_enabled"
+    description: "Enable fix for removing package from settings if app is updated or component is modified"
+    bug: "384772470"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
+    namespace: "credential_manager"
     name: "settings_activity_enabled"
     is_exported: true
     description: "Enable the Credential Manager Settings Activity APIs"
diff --git a/core/java/android/hardware/contexthub/HubEndpoint.java b/core/java/android/hardware/contexthub/HubEndpoint.java
index af92cff..6c669a3 100644
--- a/core/java/android/hardware/contexthub/HubEndpoint.java
+++ b/core/java/android/hardware/contexthub/HubEndpoint.java
@@ -296,7 +296,7 @@
                     }
 
                     if (activeSession == null || mMessageCallback == null) {
-                        if (message.getDeliveryParams().isResponseRequired()) {
+                        if (message.isResponseRequired()) {
                             try {
                                 mServiceToken.sendMessageDeliveryStatus(
                                         sessionId,
@@ -313,7 +313,7 @@
                     mMessageCallbackExecutor.execute(
                             () -> {
                                 mMessageCallback.onMessageReceived(activeSession, message);
-                                if (message.getDeliveryParams().isResponseRequired()) {
+                                if (message.isResponseRequired()) {
                                     try {
                                         mServiceToken.sendMessageDeliveryStatus(
                                                 sessionId,
diff --git a/core/java/android/hardware/contexthub/HubEndpointSession.java b/core/java/android/hardware/contexthub/HubEndpointSession.java
index f7f5636..dd6e52f 100644
--- a/core/java/android/hardware/contexthub/HubEndpointSession.java
+++ b/core/java/android/hardware/contexthub/HubEndpointSession.java
@@ -79,7 +79,7 @@
             throw new IllegalStateException("Session is already closed.");
         }
 
-        boolean isResponseRequired = message.getDeliveryParams().isResponseRequired();
+        boolean isResponseRequired = message.isResponseRequired();
         ContextHubTransaction<Void> ret =
                 new ContextHubTransaction<>(
                         isResponseRequired
diff --git a/core/java/android/hardware/contexthub/HubMessage.java b/core/java/android/hardware/contexthub/HubMessage.java
index 6373bba..8a8617d 100644
--- a/core/java/android/hardware/contexthub/HubMessage.java
+++ b/core/java/android/hardware/contexthub/HubMessage.java
@@ -29,7 +29,8 @@
 import java.util.Objects;
 
 /**
- * A class describing general messages send through the Context Hub Service.
+ * A class describing general messages send through the Context Hub Service through {@link
+ * HubEndpointSession#sendMessage}.
  *
  * @hide
  */
@@ -41,84 +42,14 @@
     private final int mMessageType;
     private final byte[] mMessageBody;
 
-    private final DeliveryParams mDeliveryParams;
+    private final boolean mResponseRequired;
     private int mMessageSequenceNumber;
 
-    /**
-     * Configurable options for message delivery. This option can be passed into {@link
-     * HubEndpointSession#sendMessage} to specify the behavior of message delivery.
-     */
-    public static class DeliveryParams {
-        private final boolean mResponseRequired;
-
-        /**
-         * @param responseRequired If true, message sent with this option will have a {@link
-         *     android.hardware.location.ContextHubTransaction.Response} when the peer received the
-         *     message.
-         */
-        public DeliveryParams(boolean responseRequired) {
-            mResponseRequired = responseRequired;
-        }
-
-        /** Get the acknowledgement requirement. */
-        public boolean isResponseRequired() {
-            return mResponseRequired;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder out = new StringBuilder();
-            out.append("DeliveryParams[");
-            out.append("responseRequired = ").append(mResponseRequired);
-            out.append("]");
-            return out.toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mResponseRequired);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj == this) {
-                return true;
-            }
-
-            if (obj instanceof DeliveryParams other) {
-                return other.mResponseRequired == mResponseRequired;
-            }
-
-            return false;
-        }
-    }
-
-    /**
-     * Default constructor for HubMessage with no response required.
-     *
-     * @param messageType the endpoint & service dependent message type
-     * @param messageBody the byte array message contents
-     */
-    public HubMessage(int messageType, @NonNull byte[] messageBody) {
+    private HubMessage(int messageType, @NonNull byte[] messageBody, boolean responseRequired) {
         Objects.requireNonNull(messageBody, "messageBody cannot be null");
         mMessageType = messageType;
         mMessageBody = messageBody;
-        mDeliveryParams = new DeliveryParams(/* responseRequired= */ false);
-    }
-
-    /**
-     * @param messageType the endpoint & service dependent message type
-     * @param messageBody the byte array message contents
-     * @param deliveryParams The message delivery parameters. See {@link HubMessage.DeliveryParams}
-     *     for more details.
-     */
-    public HubMessage(
-            int messageType, @NonNull byte[] messageBody, @NonNull DeliveryParams deliveryParams) {
-        Objects.requireNonNull(messageBody, "messageBody cannot be null");
-        Objects.requireNonNull(deliveryParams, "deliveryParams cannot be null");
-        mMessageType = messageType;
-        mMessageBody = messageBody;
-        mDeliveryParams = deliveryParams;
+        mResponseRequired = responseRequired;
     }
 
     /**
@@ -141,12 +72,10 @@
     }
 
     /**
-     * Retrieve the {@link DeliveryParams} object specifying the behavior of message delivery.
-     *
-     * @hide
+     * @return true if a response is required when the peer endpoint receives the message.
      */
-    public DeliveryParams getDeliveryParams() {
-        return mDeliveryParams;
+    public boolean isResponseRequired() {
+        return mResponseRequired;
     }
 
     /**
@@ -175,7 +104,7 @@
         mMessageBody = new byte[msgSize];
         in.readByteArray(mMessageBody);
 
-        mDeliveryParams = new DeliveryParams(in.readInt() == 1);
+        mResponseRequired = (in.readInt() == 1);
         mMessageSequenceNumber = in.readInt();
     }
 
@@ -191,7 +120,7 @@
         out.writeInt(mMessageBody.length);
         out.writeByteArray(mMessageBody);
 
-        out.writeInt(mDeliveryParams.isResponseRequired() ? 1 : 0);
+        out.writeInt(mResponseRequired ? 1 : 0);
         out.writeInt(mMessageSequenceNumber);
     }
 
@@ -217,7 +146,7 @@
         out.append("HubMessage[type = ").append(mMessageType);
         out.append(", length = ").append(mMessageBody.length);
         out.append(", messageSequenceNumber = ").append(mMessageSequenceNumber);
-        out.append(", deliveryParams = ").append(mDeliveryParams);
+        out.append(", responseRequired = ").append(mResponseRequired);
         out.append("](");
 
         if (length > 0) {
@@ -249,7 +178,7 @@
             isEqual =
                     (other.getMessageType() == mMessageType)
                             && Arrays.equals(other.getMessageBody(), mMessageBody)
-                            && (other.getDeliveryParams().equals(mDeliveryParams))
+                            && (other.isResponseRequired() == mResponseRequired)
                             && (other.getMessageSequenceNumber() == mMessageSequenceNumber);
         }
 
@@ -265,7 +194,41 @@
         return Objects.hash(
                 mMessageType,
                 Arrays.hashCode(mMessageBody),
-                mDeliveryParams,
+                mResponseRequired,
                 mMessageSequenceNumber);
     }
+
+    public static final class Builder {
+        private int mMessageType;
+        private byte[] mMessageBody;
+        private boolean mResponseRequired = false;
+
+        /**
+         * Create a builder for {@link HubMessage} with a default delivery parameters.
+         *
+         * @param messageType the endpoint & service dependent message type
+         * @param messageBody the byte array message contents
+         */
+        public Builder(int messageType, @NonNull byte[] messageBody) {
+            mMessageType = messageType;
+            mMessageBody = messageBody;
+        }
+
+        /**
+         * @param responseRequired If true, message sent with this option will have a {@link
+         *     android.hardware.location.ContextHubTransaction.Response} when the peer received the
+         *     message. Default is false.
+         */
+        @NonNull
+        public Builder setResponseRequired(boolean responseRequired) {
+            mResponseRequired = responseRequired;
+            return this;
+        }
+
+        /** Build the {@link HubMessage} object. */
+        @NonNull
+        public HubMessage build() {
+            return new HubMessage(mMessageType, mMessageBody, mResponseRequired);
+        }
+    }
 }
diff --git a/core/java/android/hardware/devicestate/DeviceState.java b/core/java/android/hardware/devicestate/DeviceState.java
index 8b4d0da..d03795d 100644
--- a/core/java/android/hardware/devicestate/DeviceState.java
+++ b/core/java/android/hardware/devicestate/DeviceState.java
@@ -25,6 +25,7 @@
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.hardware.devicestate.feature.flags.Flags;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.ArraySet;
@@ -49,7 +50,7 @@
  * @see DeviceStateManager
  */
 @SystemApi
-@FlaggedApi(android.hardware.devicestate.feature.flags.Flags.FLAG_DEVICE_STATE_PROPERTY_API)
+@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API)
 public final class DeviceState {
     /**
      * Property that indicates that a fold-in style foldable device is currently in a fully closed
@@ -178,15 +179,12 @@
      * is the default display where the app is shown, and the inner display is used by the system to
      * show a UI affordance for exiting the mode.
      *
-     * Note that this value should generally not be used, and may be removed in the future (e.g.
-     * if or when it becomes the only type of rear display mode when
-     * {@link android.hardware.devicestate.feature.flags.Flags#deviceStateRdmV2} is removed).
-     *
-     * As such, clients should strongly consider relying on {@link #PROPERTY_FEATURE_REAR_DISPLAY}
-     * instead.
+     * Clients should strongly consider relying on {@link #PROPERTY_FEATURE_REAR_DISPLAY} instead.
      *
      * @hide
      */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_DEVICE_STATE_RDM_V2)
     public static final int PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT = 1001;
 
     /** @hide */
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 7054c37..6716598 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -578,73 +578,82 @@
     /**
      * @hide
      */
-    @LongDef(flag = true, prefix = {"EVENT_FLAG_"}, value = {
-            EVENT_FLAG_DISPLAY_ADDED,
-            EVENT_FLAG_DISPLAY_CHANGED,
-            EVENT_FLAG_DISPLAY_REMOVED,
-            EVENT_FLAG_DISPLAY_REFRESH_RATE,
-            EVENT_FLAG_DISPLAY_STATE
+    @LongDef(flag = true, prefix = {"EVENT_TYPE_"}, value = {
+            EVENT_TYPE_DISPLAY_ADDED,
+            EVENT_TYPE_DISPLAY_CHANGED,
+            EVENT_TYPE_DISPLAY_REMOVED,
+            EVENT_TYPE_DISPLAY_REFRESH_RATE,
+            EVENT_TYPE_DISPLAY_STATE
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface EventFlag {}
+    public @interface EventType {}
 
     /**
      * @hide
      */
-    @LongDef(flag = true, prefix = {"PRIVATE_EVENT_FLAG_"}, value = {
-            PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS,
-            PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED,
-            PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED,
+    @LongDef(flag = true, prefix = {"PRIVATE_EVENT_TYPE_"}, value = {
+            PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS,
+            PRIVATE_EVENT_TYPE_HDR_SDR_RATIO_CHANGED,
+            PRIVATE_EVENT_TYPE_DISPLAY_CONNECTION_CHANGED,
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface PrivateEventFlag {}
+    public @interface PrivateEventType {}
 
     /**
-     * Event type for when a new display is added.
+     * Event type for when a new display is added. This notification is sent
+     * through the {@link DisplayListener#onDisplayAdded} callback method
      *
      * @see #registerDisplayListener(DisplayListener, Handler, long)
      *
      */
     @FlaggedApi(FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS)
-    public static final long EVENT_FLAG_DISPLAY_ADDED = 1L << 0;
+    public static final long EVENT_TYPE_DISPLAY_ADDED = 1L << 0;
 
     /**
-     * Event type for when a display is removed.
+     * Event type for when a display is removed. This notification is sent
+     * through the {@link DisplayListener#onDisplayRemoved} callback method
      *
      * @see #registerDisplayListener(DisplayListener, Handler, long)
      *
      */
     @FlaggedApi(FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS)
-    public static final long EVENT_FLAG_DISPLAY_REMOVED = 1L << 1;
+    public static final long EVENT_TYPE_DISPLAY_REMOVED = 1L << 1;
 
     /**
-     * Event type for when a display is changed.
+     * Event type for when a display is changed. {@link DisplayListener#onDisplayChanged} callback
+     * is triggered whenever the properties of a {@link android.view.Display}, such as size,
+     * state, density are modified.
      *
      * @see #registerDisplayListener(DisplayListener, Handler, long)
      *
      */
     @FlaggedApi(FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS)
-    public static final long EVENT_FLAG_DISPLAY_CHANGED = 1L << 2;
-
+    public static final long EVENT_TYPE_DISPLAY_CHANGED = 1L << 2;
 
     /**
-     * Event flag to register for a display's refresh rate changes.
+     * Event type for when a display's refresh rate changes.
+     * {@link DisplayListener#onDisplayChanged} callback is triggered whenever the refresh rate
+     * of the display changes. New refresh rate values can be retrieved via
+     * {@link Display#getRefreshRate()}.
      *
      * @see #registerDisplayListener(DisplayListener, Handler, long)
      */
     @FlaggedApi(FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS)
-    public static final long EVENT_FLAG_DISPLAY_REFRESH_RATE = 1L << 3;
+    public static final long EVENT_TYPE_DISPLAY_REFRESH_RATE = 1L << 3;
 
     /**
-     * Event flag to register for a display state changes.
+     * Event type for when a display state changes.
+     * {@link DisplayListener#onDisplayChanged} callback is triggered whenever the state
+     * of the display changes. New state values can be retrieved via
+     * {@link Display#getState()}.
      *
      * @see #registerDisplayListener(DisplayListener, Handler, long)
      */
     @FlaggedApi(FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS)
-    public static final long EVENT_FLAG_DISPLAY_STATE = 1L << 4;
+    public static final long EVENT_TYPE_DISPLAY_STATE = 1L << 4;
 
     /**
-     * Event flag to register for a display's brightness changes. This notification is sent
+     * Event type to register for a display's brightness changes. This notification is sent
      * through the {@link DisplayListener#onDisplayChanged} callback method. New brightness
      * values can be retrieved via {@link android.view.Display#getBrightnessInfo()}.
      *
@@ -652,10 +661,10 @@
      *
      * @hide
      */
-    public static final long PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS = 1L << 0;
+    public static final long PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS = 1L << 0;
 
     /**
-     * Event flag to register for a display's hdr/sdr ratio changes. This notification is sent
+     * Event type to register for a display's hdr/sdr ratio changes. This notification is sent
      * through the {@link DisplayListener#onDisplayChanged} callback method. New hdr/sdr
      * values can be retrieved via {@link Display#getHdrSdrRatio()}.
      *
@@ -665,15 +674,15 @@
      *
      * @hide
      */
-    public static final long PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED = 1L << 1;
+    public static final long PRIVATE_EVENT_TYPE_HDR_SDR_RATIO_CHANGED = 1L << 1;
 
     /**
-     * Event flag to register for a display's connection changed.
+     * Event type to register for a display's connection changed.
      *
      * @see #registerDisplayListener(DisplayListener, Handler, long)
      * @hide
      */
-    public static final long PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED = 1L << 2;
+    public static final long PRIVATE_EVENT_TYPE_DISPLAY_CONNECTION_CHANGED = 1L << 2;
 
 
     /** @hide */
@@ -800,8 +809,8 @@
      * @see #unregisterDisplayListener
      */
     public void registerDisplayListener(DisplayListener listener, Handler handler) {
-        registerDisplayListener(listener, handler, EVENT_FLAG_DISPLAY_ADDED
-                | EVENT_FLAG_DISPLAY_CHANGED | EVENT_FLAG_DISPLAY_REMOVED);
+        registerDisplayListener(listener, handler, EVENT_TYPE_DISPLAY_ADDED
+                | EVENT_TYPE_DISPLAY_CHANGED | EVENT_TYPE_DISPLAY_REMOVED);
     }
 
     /**
@@ -810,7 +819,7 @@
      * @param listener The listener to register.
      * @param handler The handler on which the listener should be invoked, or null
      * if the listener should be invoked on the calling thread's looper.
-     * @param eventFlags A bitmask of the event types for which this listener is subscribed.
+     * @param eventFilter A bitmask of the event types for which this listener is subscribed.
      *
      * @see #registerDisplayListener(DisplayListener, Handler)
      * @see #unregisterDisplayListener
@@ -818,9 +827,9 @@
      * @hide
      */
     public void registerDisplayListener(@NonNull DisplayListener listener,
-            @Nullable Handler handler, @EventFlag long eventFlags) {
+            @Nullable Handler handler, @EventType long eventFilter) {
         mGlobal.registerDisplayListener(listener, handler,
-                mGlobal.mapFlagsToInternalEventFlag(eventFlags, 0),
+                mGlobal.mapFiltersToInternalEventFlag(eventFilter, 0),
                 ActivityThread.currentPackageName());
     }
 
@@ -829,17 +838,17 @@
      *
      * @param listener The listener to register.
      * @param executor Executor for the thread that will be receiving the callbacks. Cannot be null.
-     * @param eventFlags A bitmask of the event types for which this listener is subscribed.
+     * @param eventFilter A bitmask of the event types for which this listener is subscribed.
      *
      * @see #registerDisplayListener(DisplayListener, Handler)
      * @see #unregisterDisplayListener
      *
      */
     @FlaggedApi(FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS)
-    public void registerDisplayListener(@NonNull Executor executor, @EventFlag long eventFlags,
+    public void registerDisplayListener(@NonNull Executor executor, @EventType long eventFilter,
             @NonNull DisplayListener listener) {
         mGlobal.registerDisplayListener(listener, executor,
-                mGlobal.mapFlagsToInternalEventFlag(eventFlags, 0),
+                mGlobal.mapFiltersToInternalEventFlag(eventFilter, 0),
                 ActivityThread.currentPackageName());
     }
 
@@ -849,8 +858,8 @@
      * @param listener The listener to register.
      * @param handler The handler on which the listener should be invoked, or null
      * if the listener should be invoked on the calling thread's looper.
-     * @param eventFlags A bitmask of the event types for which this listener is subscribed.
-     * @param privateEventFlags A bitmask of the private event types for which this listener
+     * @param eventFilter A bitmask of the event types for which this listener is subscribed.
+     * @param privateEventFilter A bitmask of the private event types for which this listener
      *                          is subscribed.
      *
      * @see #registerDisplayListener(DisplayListener, Handler)
@@ -859,10 +868,10 @@
      * @hide
      */
     public void registerDisplayListener(@NonNull DisplayListener listener,
-            @Nullable Handler handler, @EventFlag long eventFlags,
-            @PrivateEventFlag long privateEventFlags) {
+            @Nullable Handler handler, @EventType long eventFilter,
+            @PrivateEventType long privateEventFilter) {
         mGlobal.registerDisplayListener(listener, handler,
-                mGlobal.mapFlagsToInternalEventFlag(eventFlags, privateEventFlags),
+                mGlobal.mapFiltersToInternalEventFlag(eventFilter, privateEventFilter),
                 ActivityThread.currentPackageName());
     }
 
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 9030810..b5715ed 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -18,7 +18,7 @@
 
 
 import static android.app.PropertyInvalidatedCache.MODULE_SYSTEM;
-import static android.hardware.display.DisplayManager.EventFlag;
+import static android.hardware.display.DisplayManager.EventType;
 import static android.Manifest.permission.MANAGE_DISPLAYS;
 import static android.view.Display.HdrCapabilities.HdrType;
 
@@ -1737,35 +1737,35 @@
      * @return returns the bitmask of both public and private event flags unified to
      * InternalEventFlag
      */
-    public @InternalEventFlag long mapFlagsToInternalEventFlag(@EventFlag long eventFlags,
-            @DisplayManager.PrivateEventFlag long privateEventFlags) {
+    public @InternalEventFlag long mapFiltersToInternalEventFlag(@EventType long eventFlags,
+            @DisplayManager.PrivateEventType long privateEventFlags) {
         return mapPrivateEventFlags(privateEventFlags) | mapPublicEventFlags(eventFlags);
     }
 
-    private long mapPrivateEventFlags(@DisplayManager.PrivateEventFlag long privateEventFlags) {
+    private long mapPrivateEventFlags(@DisplayManager.PrivateEventType long privateEventFlags) {
         long baseEventMask = 0;
-        if ((privateEventFlags & DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS) != 0) {
+        if ((privateEventFlags & DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS) != 0) {
             baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED;
         }
 
-        if ((privateEventFlags & DisplayManager.PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED) != 0) {
+        if ((privateEventFlags & DisplayManager.PRIVATE_EVENT_TYPE_HDR_SDR_RATIO_CHANGED) != 0) {
             baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED;
         }
 
         if ((privateEventFlags
-                & DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0) {
+                & DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_CONNECTION_CHANGED) != 0) {
             baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED;
         }
         return baseEventMask;
     }
 
-    private long mapPublicEventFlags(@EventFlag long eventFlags) {
+    private long mapPublicEventFlags(@EventType long eventFlags) {
         long baseEventMask = 0;
-        if ((eventFlags & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0) {
+        if ((eventFlags & DisplayManager.EVENT_TYPE_DISPLAY_ADDED) != 0) {
             baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_ADDED;
         }
 
-        if ((eventFlags & DisplayManager.EVENT_FLAG_DISPLAY_CHANGED) != 0) {
+        if ((eventFlags & DisplayManager.EVENT_TYPE_DISPLAY_CHANGED) != 0) {
             // For backward compatibility, a client subscribing to
             // DisplayManager.EVENT_FLAG_DISPLAY_CHANGED will be enrolled to both Basic and
             // RR changes
@@ -1774,16 +1774,16 @@
         }
 
         if ((eventFlags
-                & DisplayManager.EVENT_FLAG_DISPLAY_REMOVED) != 0) {
+                & DisplayManager.EVENT_TYPE_DISPLAY_REMOVED) != 0) {
             baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_REMOVED;
         }
 
         if (Flags.displayListenerPerformanceImprovements()) {
-            if ((eventFlags & DisplayManager.EVENT_FLAG_DISPLAY_REFRESH_RATE) != 0) {
+            if ((eventFlags & DisplayManager.EVENT_TYPE_DISPLAY_REFRESH_RATE) != 0) {
                 baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE;
             }
 
-            if ((eventFlags & DisplayManager.EVENT_FLAG_DISPLAY_STATE) != 0) {
+            if ((eventFlags & DisplayManager.EVENT_TYPE_DISPLAY_STATE) != 0) {
                 baseEventMask |= INTERNAL_EVENT_FLAG_DISPLAY_STATE;
             }
         }
diff --git a/core/java/android/hardware/display/DisplayTopology.java b/core/java/android/hardware/display/DisplayTopology.java
index ba5dfc0..0e2c05f 100644
--- a/core/java/android/hardware/display/DisplayTopology.java
+++ b/core/java/android/hardware/display/DisplayTopology.java
@@ -27,10 +27,12 @@
 import android.graphics.RectF;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.DisplayMetrics;
 import android.util.IndentingPrintWriter;
 import android.util.MathUtils;
 import android.util.Pair;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.view.Display;
 
 import androidx.annotation.NonNull;
@@ -75,6 +77,24 @@
             };
 
     /**
+     * @param px The value in logical pixels
+     * @param dpi The logical density of the display
+     * @return The value in density-independent pixels
+     */
+    public static float pxToDp(float px, int dpi) {
+        return px * DisplayMetrics.DENSITY_DEFAULT / dpi;
+    }
+
+    /**
+     * @param dp The value in density-independent pixels
+     * @param dpi The logical density of the display
+     * @return The value in logical pixels
+     */
+    public static float dpToPx(float dp, int dpi) {
+        return dp * dpi / DisplayMetrics.DENSITY_DEFAULT;
+    }
+
+    /**
      * The topology tree
      */
     @Nullable
@@ -226,10 +246,9 @@
         // The optimal pair is the pair which has the smallest deviation. The deviation consists of
         // an x-axis component and a y-axis component, called xDeviation and yDeviation.
         //
-        // The deviations are like distances but a little different. They are calculated in two
-        // steps. The first step calculates both axes in a similar way. The next step compares the
-        // two values and chooses which axis to attach along. Depending on which axis is chosen,
-        // the deviation for one axis is updated. See below for details.
+        // The deviations are like distances but a little different. When they are calculated, each
+        // dimension is treated differently, depending on which edges (left+right or top+bottom) are
+        // attached.
         while (!needsParent.isEmpty()) {
             double bestDist = Double.POSITIVE_INFINITY;
             TreeNode bestChild = null, bestParent = null;
@@ -243,33 +262,32 @@
                     float parentRight = parentPos.x + parent.getWidth();
                     float parentBottom = parentPos.y + parent.getHeight();
 
-                    // This is the smaller of the two ranges minus the amount of overlap shared
-                    // between them. The "amount of overlap" is negative if there is no overlap, but
-                    // this does not make a parenting ineligible, because we allow for attaching at
-                    // the corner and for floating point error. The overlap is more negative the
-                    // farther apart the closest corner pair is.
-                    //
-                    // For each axis, this calculates (SmallerRange - Overlap). If one range lies
-                    // completely in the other (or they are equal), the axis' deviation will be
-                    // zero.
-                    //
-                    // The "SmallerRange," which refers to smaller of the widths of the two rects,
-                    // or smaller of the heights of the two rects, is added to the deviation so that
-                    // a maximum overlap results in a deviation of zero.
-                    float xSmallerRange = Math.min(child.getWidth(), parent.getWidth());
-                    float ySmallerRange = Math.min(child.getHeight(), parent.getHeight());
-                    float xOverlap
-                            = Math.min(parentRight, childRight)
-                            - Math.max(parentPos.x, childPos.x);
-                    float yOverlap
-                            = Math.min(parentBottom, childBottom)
-                            - Math.max(parentPos.y, childPos.y);
-                    float xDeviation = xSmallerRange - xOverlap;
-                    float yDeviation = ySmallerRange - yOverlap;
+                    // The "amount of overlap" indicates how much of one display is within the other
+                    // (considering one axis only). It's zero if they only share an edge and
+                    // negative if they're away from each other.
+                    // A zero or negative overlap does not make a parenting ineligible, because we
+                    // allow for attaching at the corner and for floating point error.
+                    float xOverlap =
+                            Math.min(parentRight, childRight) - Math.max(parentPos.x, childPos.x);
+                    float yOverlap =
+                            Math.min(parentBottom, childBottom) - Math.max(parentPos.y, childPos.y);
+                    float xDeviation, yDeviation;
 
                     float offset;
                     int pos;
-                    if (xDeviation <= yDeviation) {
+                    if (Math.abs(xOverlap) > Math.abs(yOverlap)) {
+                        // Deviation in each dimension is a penalty in the potential parenting. To
+                        // get the X deviation, overlap is subtracted from the lesser width so that
+                        // a maximum overlap results in a deviation of zero.
+                        // Note that because xOverlap is *subtracted* from the lesser width, no
+                        // overlap in X becomes a *penalty* if we are attaching on the top+bottom
+                        // edges.
+                        //
+                        // The Y deviation is simply the distance from the clamping edges.
+                        //
+                        // Treatment of the X and Y deviations are swapped for
+                        // POSITION_LEFT/POSITION_RIGHT attachments in the "else" block below.
+                        xDeviation = Math.min(child.getWidth(), parent.getWidth()) - xOverlap;
                         if (childPos.y < parentPos.y) {
                             yDeviation = childBottom - parentPos.y;
                             pos = POSITION_TOP;
@@ -279,6 +297,7 @@
                         }
                         offset = childPos.x - parentPos.x;
                     } else {
+                        yDeviation = Math.min(child.getHeight(), parent.getHeight()) - yOverlap;
                         if (childPos.x < parentPos.x) {
                             xDeviation = childRight - parentPos.x;
                             pos = POSITION_LEFT;
@@ -474,6 +493,22 @@
         return new DisplayTopology(rootCopy, mPrimaryDisplayId);
     }
 
+    /**
+     * Assign absolute bounds to each display. The top-left corner of the root is at position
+     * (0, 0).
+     * @return Map from logical display ID to the display's absolute bounds
+     */
+    public SparseArray<RectF> getAbsoluteBounds() {
+        Map<TreeNode, RectF> bounds = new HashMap<>();
+        getInfo(bounds, /* depths= */ null, /* parents= */ null, mRoot, /* x= */ 0, /* y= */ 0,
+                /* depth= */ 0);
+        SparseArray<RectF> boundsById = new SparseArray<>();
+        for (Map.Entry<TreeNode, RectF> entry : bounds.entrySet()) {
+            boundsById.append(entry.getKey().mDisplayId, entry.getValue());
+        }
+        return boundsById;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -575,7 +610,7 @@
     }
 
     @Nullable
-    private static TreeNode findDisplay(int displayId, TreeNode startingNode) {
+    private static TreeNode findDisplay(int displayId, @Nullable TreeNode startingNode) {
         if (startingNode == null) {
             return null;
         }
@@ -592,8 +627,8 @@
     }
 
     /**
-     * Get information about the topology that will be used for the normalization algorithm.
-     * Assigns origins to each display to compute the bounds.
+     * Get information about the topology.
+     * Assigns positions to each display to compute the bounds. The root is at position (0, 0).
      * @param bounds The map where the bounds of each display will be put
      * @param depths The map where the depths of each display in the tree will be put
      * @param parents The map where the parent of each display will be put
@@ -602,12 +637,22 @@
      * @param y The starting y position
      * @param depth The starting depth
      */
-    private static void getInfo(Map<TreeNode, RectF> bounds, Map<TreeNode, Integer> depths,
-            Map<TreeNode, TreeNode> parents, TreeNode display, float x, float y, int depth) {
-        bounds.put(display, new RectF(x, y, x + display.mWidth, y + display.mHeight));
-        depths.put(display, depth);
+    private static void getInfo(@Nullable Map<TreeNode, RectF> bounds,
+            @Nullable Map<TreeNode, Integer> depths, @Nullable Map<TreeNode, TreeNode> parents,
+            @Nullable TreeNode display, float x, float y, int depth) {
+        if (display == null) {
+            return;
+        }
+        if (bounds != null) {
+            bounds.put(display, new RectF(x, y, x + display.mWidth, y + display.mHeight));
+        }
+        if (depths != null) {
+            depths.put(display, depth);
+        }
         for (TreeNode child : display.mChildren) {
-            parents.put(child, display);
+            if (parents != null) {
+                parents.put(child, display);
+            }
             if (child.mPosition == POSITION_LEFT) {
                 getInfo(bounds, depths, parents, child, x - child.mWidth, y + child.mOffset,
                         depth + 1);
@@ -662,7 +707,7 @@
      * Ensure that the offsets of all displays within the given tree are within bounds.
      * @param display The starting node
      */
-    private void clampOffsets(TreeNode display) {
+    private void clampOffsets(@Nullable TreeNode display) {
         if (display == null) {
             return;
         }
diff --git a/core/java/android/hardware/input/InputManagerGlobal.java b/core/java/android/hardware/input/InputManagerGlobal.java
index 5c11346..3ef90e4 100644
--- a/core/java/android/hardware/input/InputManagerGlobal.java
+++ b/core/java/android/hardware/input/InputManagerGlobal.java
@@ -63,6 +63,7 @@
 import com.android.internal.os.SomeArgs;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.Executor;
@@ -76,8 +77,9 @@
 public final class InputManagerGlobal {
     private static final String TAG = "InputManagerGlobal";
     // To enable these logs, run: 'adb shell setprop log.tag.InputManagerGlobal DEBUG'
-    // (requires restart)
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    private boolean debug() {
+        return Log.isLoggable(TAG, Log.DEBUG);
+    }
 
     @GuardedBy("mInputDeviceListeners")
     @Nullable private SparseArray<InputDevice> mInputDevices;
@@ -269,16 +271,19 @@
     }
 
     private void onInputDevicesChanged(int[] deviceIdAndGeneration) {
-        if (DEBUG) {
-            Log.d(TAG, "Received input devices changed.");
+        final boolean enableDebugLogs = debug();
+        if (enableDebugLogs) {
+            Log.d(TAG, "Received input devices changed: " + Arrays.toString(deviceIdAndGeneration));
         }
 
         synchronized (mInputDeviceListeners) {
             for (int i = mInputDevices.size(); --i > 0; ) {
                 final int deviceId = mInputDevices.keyAt(i);
                 if (!containsDeviceId(deviceIdAndGeneration, deviceId)) {
-                    if (DEBUG) {
-                        Log.d(TAG, "Device removed: " + deviceId);
+                    if (enableDebugLogs) {
+                        final InputDevice device = mInputDevices.valueAt(i);
+                        final String name = device != null ? device.getName() : "<null>";
+                        Log.d(TAG, "Device removed: " + deviceId + " (" + name + ")");
                     }
                     mInputDevices.removeAt(i);
                     if (mInputDeviceSensorManager != null) {
@@ -297,8 +302,9 @@
                     if (device != null) {
                         final int generation = deviceIdAndGeneration[i + 1];
                         if (device.getGeneration() != generation) {
-                            if (DEBUG) {
-                                Log.d(TAG, "Device changed: " + deviceId);
+                            if (enableDebugLogs) {
+                                Log.d(TAG, "Device changed: " + deviceId + " ("
+                                        + device.getName() + ")");
                             }
                             mInputDevices.setValueAt(index, null);
                             if (mInputDeviceSensorManager != null) {
@@ -309,7 +315,7 @@
                         }
                     }
                 } else {
-                    if (DEBUG) {
+                    if (enableDebugLogs) {
                         Log.d(TAG, "Device added: " + deviceId);
                     }
                     mInputDevices.put(deviceId, null);
@@ -517,7 +523,7 @@
     }
 
     private void onTabletModeChanged(long whenNanos, boolean inTabletMode) {
-        if (DEBUG) {
+        if (debug()) {
             Log.d(TAG, "Received tablet mode changed: "
                     + "whenNanos=" + whenNanos + ", inTabletMode=" + inTabletMode);
         }
diff --git a/core/java/android/hardware/input/KeyGestureEvent.java b/core/java/android/hardware/input/KeyGestureEvent.java
index 9f8505f..66d073f 100644
--- a/core/java/android/hardware/input/KeyGestureEvent.java
+++ b/core/java/android/hardware/input/KeyGestureEvent.java
@@ -119,16 +119,16 @@
     public static final int KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW = 69;
     public static final int KEY_GESTURE_TYPE_MINIMIZE_FREEFORM_WINDOW = 70;
     public static final int KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW = 71;
-    public static final int KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_IN = 72;
-    public static final int KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_OUT = 73;
+    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN = 72;
+    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT = 73;
     public static final int KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION = 74;
     public static final int KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK = 75;
     public static final int KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW = 76;
     public static final int KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB = 77;
-    public static final int KEY_GESTURE_TYPE_MAGNIFIER_PAN_LEFT = 78;
-    public static final int KEY_GESTURE_TYPE_MAGNIFIER_PAN_RIGHT = 79;
-    public static final int KEY_GESTURE_TYPE_MAGNIFIER_PAN_UP = 80;
-    public static final int KEY_GESTURE_TYPE_MAGNIFIER_PAN_DOWN = 81;
+    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT = 78;
+    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT = 79;
+    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP = 80;
+    public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN = 81;
 
     public static final int FLAG_CANCELLED = 1;
 
@@ -215,16 +215,16 @@
             KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW,
             KEY_GESTURE_TYPE_MINIMIZE_FREEFORM_WINDOW,
             KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW,
-            KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_IN,
-            KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_OUT,
+            KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN,
+            KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT,
             KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION,
             KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK,
             KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW,
             KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB,
-            KEY_GESTURE_TYPE_MAGNIFIER_PAN_LEFT,
-            KEY_GESTURE_TYPE_MAGNIFIER_PAN_RIGHT,
-            KEY_GESTURE_TYPE_MAGNIFIER_PAN_UP,
-            KEY_GESTURE_TYPE_MAGNIFIER_PAN_DOWN,
+            KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT,
+            KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT,
+            KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP,
+            KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface KeyGestureType {
@@ -787,10 +787,10 @@
                 return "KEY_GESTURE_TYPE_MINIMIZE_FREEFORM_WINDOW";
             case KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW:
                 return "KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW";
-            case KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_IN:
-                return "KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_IN";
-            case KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_OUT:
-                return "KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_OUT";
+            case KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN:
+                return "KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN";
+            case KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT:
+                return "KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT";
             case KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION:
                 return "KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION";
             case KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK:
@@ -799,14 +799,14 @@
                 return "KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW";
             case KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB:
                 return "KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB";
-            case KEY_GESTURE_TYPE_MAGNIFIER_PAN_LEFT:
-                return "KEY_GESTURE_TYPE_MAGNIFIER_PAN_LEFT";
-            case KEY_GESTURE_TYPE_MAGNIFIER_PAN_RIGHT:
-                return "KEY_GESTURE_TYPE_MAGNIFIER_PAN_RIGHT";
-            case KEY_GESTURE_TYPE_MAGNIFIER_PAN_UP:
-                return "KEY_GESTURE_TYPE_MAGNIFIER_PAN_UP";
-            case KEY_GESTURE_TYPE_MAGNIFIER_PAN_DOWN:
-                return "KEY_GESTURE_TYPE_MAGNIFIER_PAN_DOWN";
+            case KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT:
+                return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT";
+            case KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT:
+                return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT";
+            case KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP:
+                return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP";
+            case KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN:
+                return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN";
             default:
                 return Integer.toHexString(value);
         }
diff --git a/core/java/android/inputmethodservice/InlineSuggestionSession.java b/core/java/android/inputmethodservice/InlineSuggestionSession.java
index 1cc64f9..4c90750 100644
--- a/core/java/android/inputmethodservice/InlineSuggestionSession.java
+++ b/core/java/android/inputmethodservice/InlineSuggestionSession.java
@@ -29,6 +29,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Log;
+import android.view.autofill.AutofillFeatureFlags;
 import android.view.autofill.AutofillId;
 import android.view.inputmethod.InlineSuggestionsRequest;
 import android.view.inputmethod.InlineSuggestionsResponse;
@@ -81,6 +82,7 @@
     @Nullable
     private Boolean mPreviousResponseIsEmpty;
 
+    private boolean mAlwaysNotifyAutofill = false;
 
     /**
      * Indicates whether {@link #makeInlineSuggestionRequestUncheck()} has been called or not,
@@ -105,6 +107,7 @@
         mResponseConsumer = responseConsumer;
         mInlineSuggestionSessionController = inlineSuggestionSessionController;
         mMainThreadHandler = mainThreadHandler;
+        mAlwaysNotifyAutofill = AutofillFeatureFlags.isImproveFillDialogEnabled();
     }
 
     @MainThread
@@ -176,6 +179,9 @@
         try {
             final InlineSuggestionsRequest request = mRequestSupplier.apply(
                     mRequestInfo.getUiExtras());
+            if (mAlwaysNotifyAutofill) {
+                mResponseCallback = new InlineSuggestionsResponseCallbackImpl(this);
+            }
             if (request == null) {
                 if (DEBUG) {
                     Log.d(TAG, "onCreateInlineSuggestionsRequest() returned null request");
@@ -184,7 +190,9 @@
             } else {
                 request.setHostInputToken(mHostInputTokenSupplier.get());
                 request.filterContentTypes();
-                mResponseCallback = new InlineSuggestionsResponseCallbackImpl(this);
+                if (!mAlwaysNotifyAutofill) {
+                    mResponseCallback = new InlineSuggestionsResponseCallbackImpl(this);
+                }
                 mCallback.onInlineSuggestionsRequest(request, mResponseCallback);
             }
         } catch (RemoteException e) {
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index d54dbad9..c51ad9e 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -431,13 +431,8 @@
          * android.os.Build.VERSION_CODES_FULL}.
          */
         @FlaggedApi(Flags.FLAG_MAJOR_MINOR_VERSIONING_SCHEME)
-        public static final int SDK_INT_FULL;
-
-        static {
-            SDK_INT_FULL = VERSION_CODES_FULL.SDK_INT_MULTIPLIER
-                * SystemProperties.getInt("ro.build.version.sdk", 0)
-                + SystemProperties.getInt("ro.build.version.sdk_minor", 0);
-        }
+        public static final int SDK_INT_FULL = parseFullVersion(SystemProperties.get(
+                    "ro.build.version.sdk_full", ""));
 
         /**
          * The SDK version of the software that <em>initially</em> shipped on
diff --git a/core/java/android/os/IHintManager.aidl b/core/java/android/os/IHintManager.aidl
index 56a089a..5128e91 100644
--- a/core/java/android/os/IHintManager.aidl
+++ b/core/java/android/os/IHintManager.aidl
@@ -39,12 +39,18 @@
      * Throws UnsupportedOperationException if ADPF is not supported, and IllegalStateException
      * if creation is supported but fails.
      */
-    IHintSession createHintSessionWithConfig(in IBinder token, in SessionTag tag,
+    SessionCreationReturn createHintSessionWithConfig(in IBinder token, in SessionTag tag,
             in SessionCreationConfig creationConfig, out SessionConfig config);
 
     void setHintSessionThreads(in IHintSession hintSession, in int[] tids);
     int[] getHintSessionThreadIds(in IHintSession hintSession);
 
+    parcelable SessionCreationReturn {
+        IHintSession session;
+        // True if the graphics pipeline thread limit is being exceeded
+        boolean pipelineThreadLimitExceeded = false;
+    }
+
     /**
      * Returns FMQ channel information for the caller, which it associates to a binder token.
      *
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 507bcb8..08f68f1 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -4206,12 +4206,16 @@
     private boolean getUserRestrictionFromQuery(@NonNull Pair<String, Integer> restrictionPerUser) {
         return UserManagerCache.getUserRestrictionFromQuery(
                 (Pair<String, Integer> q) -> mService.hasUserRestriction(q.first, q.second),
+                // bypass cache if the flag is disabled
+                (Pair<String, Integer> q) -> !android.multiuser.Flags.cacheUserRestrictionsReadOnly(),
                 restrictionPerUser);
     }
 
     /** @hide */
     public static final void invalidateUserRestriction() {
-        UserManagerCache.invalidateUserRestrictionFromQuery();
+        if (android.multiuser.Flags.cacheUserRestrictionsReadOnly()) {
+            UserManagerCache.invalidateUserRestrictionFromQuery();
+        }
     }
 
     /**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a0c2915..6e58780 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9421,6 +9421,13 @@
                 "even_dimmer_min_nits";
 
         /**
+         * Setting that holds EM_VALUE (proprietary)
+         *
+         * @hide
+         */
+        public static final String EM_VALUE =
+                "em_value";
+        /**
          * List of the enabled print services.
          *
          * N and beyond uses {@link #DISABLED_PRINT_SERVICES}. But this might be used in an upgrade
diff --git a/core/java/android/security/advancedprotection/AdvancedProtectionFeature.java b/core/java/android/security/advancedprotection/AdvancedProtectionFeature.java
index d476d96..a086bf7 100644
--- a/core/java/android/security/advancedprotection/AdvancedProtectionFeature.java
+++ b/core/java/android/security/advancedprotection/AdvancedProtectionFeature.java
@@ -30,25 +30,26 @@
 @FlaggedApi(Flags.FLAG_AAPM_API)
 @SystemApi
 public final class AdvancedProtectionFeature implements Parcelable {
-    private final int mId;
+    private final String mId;
 
     /**
      * Create an object identifying an Advanced Protection feature for AdvancedProtectionManager
-     * @param id Feature identifier. It is used by Settings screens to display information about
-     *           this feature.
+     * @param id A unique ID to identify this feature. It is used by Settings screens to display
+     *           information about this feature.
      */
-    public AdvancedProtectionFeature(@AdvancedProtectionManager.FeatureId int id) {
+    public AdvancedProtectionFeature(@NonNull String id) {
         mId = id;
     }
 
     private AdvancedProtectionFeature(Parcel in) {
-        mId = in.readInt();
+        mId = in.readString8();
     }
 
     /**
      * @return the unique ID representing this feature
      */
-    public int getId() {
+    @NonNull
+    public String getId() {
         return mId;
     }
 
@@ -59,7 +60,7 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mId);
+        dest.writeString8(mId);
     }
 
     @NonNull
diff --git a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
index ea01fc9..59628e8 100644
--- a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
+++ b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
@@ -24,18 +24,17 @@
 import android.Manifest;
 import android.annotation.CallbackExecutor;
 import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
+import android.annotation.SdkConstant;
+import android.annotation.StringDef;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
-import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.Intent;
-import android.net.wifi.WifiManager;
 import android.os.Binder;
 import android.os.RemoteException;
-import android.os.UserManager;
 import android.security.Flags;
 import android.util.Log;
 
@@ -60,57 +59,54 @@
     private static final String TAG = "AdvancedProtectionMgr";
 
     /**
-     * Advanced Protection's identifier for setting policies or restrictions in
-     * {@link DevicePolicyManager}.
+     * Advanced Protection's identifier for setting policies or restrictions in DevicePolicyManager.
      *
      * @hide */
     public static final String ADVANCED_PROTECTION_SYSTEM_ENTITY =
             "android.security.advancedprotection";
 
     /**
-     * Feature identifier for disallowing connections to 2G networks.
+     * Feature identifier for disallowing 2G.
      *
-     * @see UserManager#DISALLOW_CELLULAR_2G
      * @hide */
     @SystemApi
-    public static final int FEATURE_ID_DISALLOW_CELLULAR_2G = 0;
+    public static final String FEATURE_ID_DISALLOW_CELLULAR_2G =
+            "android.security.advancedprotection.feature_disallow_2g";
 
     /**
-     * Feature identifier for disallowing installs of apps from unknown sources.
+     * Feature identifier for disallowing install of unknown sources.
      *
-     * @see UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY
      * @hide */
     @SystemApi
-    public static final int FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES = 1;
+    public static final String FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES =
+            "android.security.advancedprotection.feature_disallow_install_unknown_sources";
 
     /**
-     * Feature identifier for disallowing USB connections.
+     * Feature identifier for disallowing USB.
      *
      * @hide */
     @SystemApi
-    public static final int FEATURE_ID_DISALLOW_USB = 2;
+    public static final String FEATURE_ID_DISALLOW_USB =
+            "android.security.advancedprotection.feature_disallow_usb";
 
     /**
-     * Feature identifier for disallowing connections to Wi-Fi Wired Equivalent Privacy (WEP)
-     * networks.
+     * Feature identifier for disallowing WEP.
      *
-     * @see WifiManager#isWepSupported()
      * @hide */
     @SystemApi
-    public static final int FEATURE_ID_DISALLOW_WEP = 3;
+    public static final String FEATURE_ID_DISALLOW_WEP =
+            "android.security.advancedprotection.feature_disallow_wep";
 
     /**
-     * Feature identifier for enabling the Memory Tagging Extension (MTE). MTE is a CPU extension
-     * that allows to protect against certain classes of security problems at a small runtime
-     * performance cost overhead.
+     * Feature identifier for enabling MTE.
      *
-     * @see DevicePolicyManager#setMtePolicy(int)
      * @hide */
     @SystemApi
-    public static final int FEATURE_ID_ENABLE_MTE = 4;
+    public static final String FEATURE_ID_ENABLE_MTE =
+            "android.security.advancedprotection.feature_enable_mte";
 
     /** @hide */
-    @IntDef(prefix = { "FEATURE_ID_" }, value = {
+    @StringDef(prefix = { "FEATURE_ID_" }, value = {
             FEATURE_ID_DISALLOW_CELLULAR_2G,
             FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES,
             FEATURE_ID_DISALLOW_USB,
@@ -120,7 +116,7 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface FeatureId {}
 
-    private static final Set<Integer> ALL_FEATURE_IDS = Set.of(
+    private static final Set<String> ALL_FEATURE_IDS = Set.of(
             FEATURE_ID_DISALLOW_CELLULAR_2G,
             FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES,
             FEATURE_ID_DISALLOW_USB,
@@ -139,6 +135,9 @@
      * Output: Nothing.
      *
      * @hide */
+    @SystemApi
+    @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+    @FlaggedApi(android.security.Flags.FLAG_AAPM_API)
     public static final String ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG =
             "android.security.advancedprotection.action.SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG";
 
@@ -148,6 +147,7 @@
      *
      * @hide */
     @FeatureId
+    @SystemApi
     public static final String EXTRA_SUPPORT_DIALOG_FEATURE =
             "android.security.advancedprotection.extra.SUPPORT_DIALOG_FEATURE";
 
@@ -157,41 +157,37 @@
      *
      * @hide */
     @SupportDialogType
+    @SystemApi
     public static final String EXTRA_SUPPORT_DIALOG_TYPE =
             "android.security.advancedprotection.extra.SUPPORT_DIALOG_TYPE";
 
     /**
-     * Type for {@link #EXTRA_SUPPORT_DIALOG_TYPE} indicating an unknown action was blocked by
-     * advanced protection, hence the support dialog should display a default explanation.
-     *
-     * @hide */
-    public static final int SUPPORT_DIALOG_TYPE_UNKNOWN = 0;
-
-    /**
      * Type for {@link #EXTRA_SUPPORT_DIALOG_TYPE} indicating a user performed an action that was
      * blocked by advanced protection.
      *
      * @hide */
-    public static final int SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION = 1;
+    @SystemApi
+    public static final String SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION =
+            "android.security.advancedprotection.type_blocked_interaction";
 
     /**
      * Type for {@link #EXTRA_SUPPORT_DIALOG_TYPE} indicating a user pressed on a setting toggle
      * that was disabled by advanced protection.
      *
      * @hide */
-    public static final int SUPPORT_DIALOG_TYPE_DISABLED_SETTING = 2;
+    @SystemApi
+    public static final String SUPPORT_DIALOG_TYPE_DISABLED_SETTING =
+            "android.security.advancedprotection.type_disabled_setting";
 
     /** @hide */
-    @IntDef(prefix = { "SUPPORT_DIALOG_TYPE_" }, value = {
-            SUPPORT_DIALOG_TYPE_UNKNOWN,
+    @StringDef(prefix = { "SUPPORT_DIALOG_TYPE_" }, value = {
             SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION,
             SUPPORT_DIALOG_TYPE_DISABLED_SETTING,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface SupportDialogType {}
 
-    private static final Set<Integer> ALL_SUPPORT_DIALOG_TYPES = Set.of(
-            SUPPORT_DIALOG_TYPE_UNKNOWN,
+    private static final Set<String> ALL_SUPPORT_DIALOG_TYPES = Set.of(
             SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION,
             SUPPORT_DIALOG_TYPE_DISABLED_SETTING);
 
@@ -328,13 +324,15 @@
      *                disabled by advanced protection.
      * @hide
      */
-    public static @NonNull Intent createSupportIntent(@FeatureId int featureId,
-            @SupportDialogType int type) {
+    @SystemApi
+    public @NonNull Intent createSupportIntent(@NonNull @FeatureId String featureId,
+            @Nullable @SupportDialogType String type) {
+        Objects.requireNonNull(featureId);
         if (!ALL_FEATURE_IDS.contains(featureId)) {
             throw new IllegalArgumentException(featureId + " is not a valid feature ID. See"
                     + " FEATURE_ID_* APIs.");
         }
-        if (!ALL_SUPPORT_DIALOG_TYPES.contains(type)) {
+        if (type != null && !ALL_SUPPORT_DIALOG_TYPES.contains(type)) {
             throw new IllegalArgumentException(type + " is not a valid type. See"
                     + " SUPPORT_DIALOG_TYPE_* APIs.");
         }
@@ -342,19 +340,21 @@
         Intent intent = new Intent(ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG);
         intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
         intent.putExtra(EXTRA_SUPPORT_DIALOG_FEATURE, featureId);
-        intent.putExtra(EXTRA_SUPPORT_DIALOG_TYPE, type);
+        if (type != null) {
+            intent.putExtra(EXTRA_SUPPORT_DIALOG_TYPE, type);
+        }
         return intent;
     }
 
     /** @hide */
-    public static @NonNull Intent createSupportIntentForPolicyIdentifierOrRestriction(
-            @NonNull String identifier, @SupportDialogType int type) {
+    public @NonNull Intent createSupportIntentForPolicyIdentifierOrRestriction(
+            @NonNull String identifier, @Nullable @SupportDialogType String type) {
         Objects.requireNonNull(identifier);
-        if (!ALL_SUPPORT_DIALOG_TYPES.contains(type)) {
+        if (type != null && !ALL_SUPPORT_DIALOG_TYPES.contains(type)) {
             throw new IllegalArgumentException(type + " is not a valid type. See"
                     + " SUPPORT_DIALOG_TYPE_* APIs.");
         }
-        final int featureId;
+        final String featureId;
         if (DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY.equals(identifier)) {
             featureId = FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES;
         } else if (DISALLOW_CELLULAR_2G.equals(identifier)) {
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index 4f74198..880622a 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -221,13 +221,13 @@
 
     @Override
     public boolean setControl(@Nullable InsetsSourceControl control, int[] showTypes,
-            int[] hideTypes, int[] cancelTypes) {
+            int[] hideTypes, int[] cancelTypes, int[] transientTypes) {
         if (Flags.refactorInsetsController()) {
-            return super.setControl(control, showTypes, hideTypes, cancelTypes);
+            return super.setControl(control, showTypes, hideTypes, cancelTypes, transientTypes);
         } else {
             ImeTracing.getInstance().triggerClientDump("ImeInsetsSourceConsumer#setControl",
                     mController.getHost().getInputMethodManager(), null /* icProto */);
-            if (!super.setControl(control, showTypes, hideTypes, cancelTypes)) {
+            if (!super.setControl(control, showTypes, hideTypes, cancelTypes, transientTypes)) {
                 return false;
             }
             if (control == null && !mIsRequestedVisibleAwaitingLeash) {
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index b0813f3..c174fbe 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -959,6 +959,7 @@
         final @InsetsType int[] showTypes = new int[1];
         final @InsetsType int[] hideTypes = new int[1];
         final @InsetsType int[] cancelTypes = new int[1];
+        final @InsetsType int[] transientTypes = new int[1];
         ImeTracker.Token statsToken = null;
 
         // Ensure to update all existing source consumers
@@ -984,7 +985,7 @@
 
             // control may be null, but we still need to update the control to null if it got
             // revoked.
-            consumer.setControl(control, showTypes, hideTypes, cancelTypes);
+            consumer.setControl(control, showTypes, hideTypes, cancelTypes, transientTypes);
         }
 
         // Ensure to create source consumers if not available yet.
@@ -992,7 +993,7 @@
             for (int i = mTmpControlArray.size() - 1; i >= 0; i--) {
                 final InsetsSourceControl control = mTmpControlArray.valueAt(i);
                 getSourceConsumer(control.getId(), control.getType())
-                        .setControl(control, showTypes, hideTypes, cancelTypes);
+                        .setControl(control, showTypes, hideTypes, cancelTypes, transientTypes);
             }
         }
 
@@ -1020,10 +1021,16 @@
                 handlePendingControlRequest(statsToken);
             } else {
                 if (showTypes[0] != 0) {
-                    applyAnimation(showTypes[0], true /* show */, false /* fromIme */, statsToken);
+                    applyAnimation(showTypes[0], true /* show */, false /* fromIme */,
+                            false /* skipsCallbacks */, statsToken);
                 }
                 if (hideTypes[0] != 0) {
-                    applyAnimation(hideTypes[0], false /* show */, false /* fromIme */, statsToken);
+                    applyAnimation(hideTypes[0], false /* show */, false /* fromIme */,
+                            // The animation of hiding transient types shouldn't be detected by the
+                            // app. Otherwise, it might be able to react to the callbacks and cause
+                            // flickering.
+                            (hideTypes[0] & ~transientTypes[0]) == 0 /* skipsCallbacks */,
+                            statsToken);
                 }
             }
         } else {
@@ -1033,7 +1040,8 @@
                                 ImeTracker.TYPE_SHOW, ImeTracker.ORIGIN_CLIENT,
                                 SoftInputShowHideReason.CONTROLS_CHANGED,
                                 mHost.isHandlingPointerEvent() /* fromUser */);
-                applyAnimation(showTypes[0], true /* show */, false /* fromIme */, newStatsToken);
+                applyAnimation(showTypes[0], true /* show */, false /* fromIme */,
+                        false /* skipsCallbacks */, newStatsToken);
             }
             if (hideTypes[0] != 0) {
                 final var newStatsToken =
@@ -1041,7 +1049,12 @@
                                 ImeTracker.TYPE_HIDE, ImeTracker.ORIGIN_CLIENT,
                                 SoftInputShowHideReason.CONTROLS_CHANGED,
                                 mHost.isHandlingPointerEvent() /* fromUser */);
-                applyAnimation(hideTypes[0], false /* show */, false /* fromIme */, newStatsToken);
+                applyAnimation(hideTypes[0], false /* show */, false /* fromIme */,
+                        // The animation of hiding transient types shouldn't be detected by the app.
+                        // Otherwise, it might be able to react to the callbacks and cause
+                        // flickering.
+                        (hideTypes[0] & ~transientTypes[0]) == 0 /* skipsCallbacks */,
+                        newStatsToken);
             }
         }
 
@@ -1174,7 +1187,8 @@
             // TODO(b/353463205) check if this is needed here
             ImeTracker.forLatency().onShown(statsToken, ActivityThread::currentApplication);
         }
-        applyAnimation(typesReady, true /* show */, fromIme, statsToken);
+        applyAnimation(typesReady, true /* show */, fromIme, false /* skipsCallbacks */,
+                statsToken);
     }
 
     /**
@@ -1287,7 +1301,8 @@
             handlePendingControlRequest(statsToken);
             getImeSourceConsumer().removeSurface();
         }
-        applyAnimation(typesReady, false /* show */, fromIme, statsToken);
+        applyAnimation(typesReady, false /* show */, fromIme, false /* skipsCallbacks */,
+                statsToken);
     }
 
     @Override
@@ -2007,24 +2022,24 @@
 
     @VisibleForTesting
     public void applyAnimation(@InsetsType final int types, boolean show, boolean fromIme,
-            @Nullable ImeTracker.Token statsToken) {
+            boolean skipsCallbacks, @Nullable ImeTracker.Token statsToken) {
         // TODO(b/166736352): We should only skip the animation of specific types, not all types.
-        boolean skipAnim = false;
+        boolean skipsAnim = false;
         if ((types & ime()) != 0) {
             final InsetsSourceControl imeControl = mImeSourceConsumer.getControl();
             // Skip showing animation once that made by system for some reason.
             // (e.g. starting window with IME snapshot)
             if (imeControl != null) {
-                skipAnim = imeControl.getAndClearSkipAnimationOnce() && show
+                skipsAnim = imeControl.getAndClearSkipAnimationOnce() && show
                         && mImeSourceConsumer.hasViewFocusWhenWindowFocusGain();
             }
         }
-        applyAnimation(types, show, fromIme, skipAnim, statsToken);
+        applyAnimation(types, show, fromIme, skipsAnim, skipsCallbacks, statsToken);
     }
 
     @VisibleForTesting
     public void applyAnimation(@InsetsType final int types, boolean show, boolean fromIme,
-            boolean skipAnim, @Nullable ImeTracker.Token statsToken) {
+            boolean skipsAnim, boolean skipsCallbacks, @Nullable ImeTracker.Token statsToken) {
         if (types == 0) {
             // nothing to animate.
             if (DEBUG) Log.d(TAG, "applyAnimation, nothing to animate. Stopping here");
@@ -2040,7 +2055,7 @@
         boolean hasAnimationCallbacks = mHost.hasAnimationCallbacks();
         final InternalAnimationControlListener listener = new InternalAnimationControlListener(
                 show, hasAnimationCallbacks, types, mHost.getSystemBarsBehavior(),
-                skipAnim || mAnimationsDisabled, mHost.dipToPx(FLOATING_IME_BOTTOM_INSET_DP),
+                skipsAnim || mAnimationsDisabled, mHost.dipToPx(FLOATING_IME_BOTTOM_INSET_DP),
                 mLoggingListener, mJankContext);
 
         // We are about to playing the default animation (show/hide). Passing a null frame indicates
@@ -2050,7 +2065,7 @@
                 listener /* insetsAnimationSpec */,
                 show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE,
                 show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN,
-                !hasAnimationCallbacks /* useInsetsAnimationThread */, statsToken,
+                !hasAnimationCallbacks || skipsCallbacks /* useInsetsAnimationThread */, statsToken,
                 false /* fromPredictiveBack */);
     }
 
@@ -2173,12 +2188,12 @@
                         new InsetsSourceControl(ID_IME_CAPTION_BAR, captionBar(),
                                 null /* leash */, false /* initialVisible */,
                                 new Point(), Insets.NONE),
-                        new int[1], new int[1], new int[1]);
+                        new int[1], new int[1], new int[1], new int[1]);
             } else {
                 mState.removeSource(ID_IME_CAPTION_BAR);
                 InsetsSourceConsumer sourceConsumer = mSourceConsumers.get(ID_IME_CAPTION_BAR);
                 if (sourceConsumer != null) {
-                    sourceConsumer.setControl(null, new int[1], new int[1], new int[1]);
+                    sourceConsumer.setControl(null, new int[1], new int[1], new int[1], new int[1]);
                 }
             }
             mHost.notifyInsetsChanged();
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 17f33c1..e8e6621 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -130,7 +130,10 @@
      * @return Whether the control has changed from the server
      */
     public boolean setControl(@Nullable InsetsSourceControl control,
-            @InsetsType int[] showTypes, @InsetsType int[] hideTypes, int[] cancelTypes) {
+            @InsetsType int[] showTypes,
+            @InsetsType int[] hideTypes,
+            @InsetsType int[] cancelTypes,
+            @InsetsType int[] transientTypes) {
         if (Objects.equals(mSourceControl, control)) {
             if (mSourceControl != null && mSourceControl != control) {
                 mSourceControl.release(SurfaceControl::release);
@@ -185,6 +188,9 @@
                 } else {
                     hideTypes[0] |= mType;
                 }
+                if (lastControl != null && lastControl.isFake()) {
+                    transientTypes[0] |= mType;
+                }
             } else {
                 // We are gaining control, but don't need to run an animation.
                 // However make sure that the leash visibility is still up to date.
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
index acbd95bf..7f2f0e8 100644
--- a/core/java/android/view/InsetsSourceControl.java
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -142,6 +142,10 @@
         return mInsetsHint;
     }
 
+    public boolean isFake() {
+        return mLeash == null && Insets.NONE.equals(mInsetsHint);
+    }
+
     public void setSkipAnimationOnce(boolean skipAnimation) {
         mSkipAnimationOnce = skipAnimation;
     }
diff --git a/core/java/android/view/autofill/AutofillFeatureFlags.java b/core/java/android/view/autofill/AutofillFeatureFlags.java
index d527007..206e47f 100644
--- a/core/java/android/view/autofill/AutofillFeatureFlags.java
+++ b/core/java/android/view/autofill/AutofillFeatureFlags.java
@@ -16,6 +16,8 @@
 
 package android.view.autofill;
 
+import static android.service.autofill.Flags.improveFillDialogAconfig;
+
 import android.annotation.SuppressLint;
 import android.annotation.TestApi;
 import android.provider.DeviceConfig;
@@ -662,7 +664,7 @@
     public static boolean isImproveFillDialogEnabled() {
         // TODO(b/266379948): Add condition for checking whether device has PCC first
 
-        return DeviceConfig.getBoolean(
+        return improveFillDialogAconfig() && DeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_AUTOFILL,
                 DEVICE_CONFIG_IMPROVE_FILL_DIALOG_ENABLED,
                 DEFAULT_IMPROVE_FILL_DIALOG_ENABLED);
diff --git a/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java b/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java
index 3a008aa..eca798d 100644
--- a/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java
+++ b/core/java/android/view/inputmethod/IInputMethodManagerGlobalInvoker.java
@@ -490,6 +490,20 @@
     }
 
     @AnyThread
+    @RequiresPermission(Manifest.permission.TEST_INPUT_METHOD)
+    static boolean shouldShowImeSwitcherButtonForTest() {
+        final IInputMethodManager service = getService();
+        if (service == null) {
+            return false;
+        }
+        try {
+            return service.shouldShowImeSwitcherButtonForTest();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    @AnyThread
     @Nullable
     @RequiresPermission(value = Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)
     static InputMethodSubtype getCurrentInputMethodSubtype(@UserIdInt int userId) {
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index d5f471e..e904345f 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -992,23 +992,7 @@
         private void setCurrentRootViewLocked(ViewRootImpl rootView) {
             final boolean wasEmpty = mCurRootView == null;
             if (Flags.refactorInsetsController() && !wasEmpty && mCurRootView != rootView) {
-                final int softInputMode = mCurRootView.mWindowAttributes.softInputMode;
-                final int state =
-                        softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
-                if (state == WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) {
-                    // when losing input focus (e.g., by going to another window), we reset the
-                    // requestedVisibleTypes of WindowInsetsController by hiding the IME
-                    final var statsToken = ImeTracker.forLogging().onStart(
-                            ImeTracker.TYPE_HIDE, ImeTracker.ORIGIN_CLIENT,
-                            SoftInputShowHideReason.HIDE_WINDOW_LOST_FOCUS,
-                            false /* fromUser */);
-                    if (DEBUG) {
-                        Log.d(TAG, "setCurrentRootViewLocked, hiding IME because "
-                                + "of STATE_ALWAYS_HIDDEN");
-                    }
-                    mCurRootView.getInsetsController().hide(WindowInsets.Type.ime(),
-                            false /* fromIme */, statsToken);
-                }
+                onImeFocusLost(mCurRootView);
             }
 
             mImeDispatcher.switchRootView(mCurRootView, rootView);
@@ -1019,6 +1003,26 @@
         }
     }
 
+    private void onImeFocusLost(@NonNull ViewRootImpl previousRootView) {
+        final int softInputMode = previousRootView.mWindowAttributes.softInputMode;
+        final int state =
+                softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
+        if (state == WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) {
+            // when losing input focus (e.g., by going to another window), we reset the
+            // requestedVisibleTypes of WindowInsetsController by hiding the IME
+            final var statsToken = ImeTracker.forLogging().onStart(
+                    ImeTracker.TYPE_HIDE, ImeTracker.ORIGIN_CLIENT,
+                    SoftInputShowHideReason.HIDE_WINDOW_LOST_FOCUS,
+                    false /* fromUser */);
+            if (DEBUG) {
+                Log.d(TAG, "onImeFocusLost, hiding IME because "
+                        + "of STATE_ALWAYS_HIDDEN");
+            }
+            previousRootView.getInsetsController().hide(WindowInsets.Type.ime(),
+                    false /* fromIme */, statsToken);
+        }
+    }
+
     /** @hide */
     public DelegateImpl getDelegate() {
         return mDelegate;
@@ -4536,6 +4540,19 @@
     }
 
     /**
+     * A test API for CTS to check whether the IME Switcher button should be shown when the IME
+     * is shown.
+     *
+     * @hide
+     */
+    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
+    @TestApi
+    @RequiresPermission(Manifest.permission.TEST_INPUT_METHOD)
+    public boolean shouldShowImeSwitcherButtonForTest() {
+        return IInputMethodManagerGlobalInvoker.shouldShowImeSwitcherButtonForTest();
+    }
+
+    /**
      * A test API for CTS to check whether there are any pending IME visibility requests.
      *
      * @return {@code true} iff there are pending IME visibility requests.
diff --git a/core/java/android/view/inputmethod/flags.aconfig b/core/java/android/view/inputmethod/flags.aconfig
index 41567fb..4258ca4 100644
--- a/core/java/android/view/inputmethod/flags.aconfig
+++ b/core/java/android/view/inputmethod/flags.aconfig
@@ -194,3 +194,14 @@
   is_fixed_read_only: true
   is_exported: true
 }
+
+flag {
+  name: "fallback_display_for_secondary_user_on_secondary_display"
+  namespace: "input_method"
+  description: "Feature flag to fix the fallback display bug for visible background users"
+  bug: "383228193"
+  is_fixed_read_only: true
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index e600b4f..e7fa510 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -59,6 +59,7 @@
 import android.view.animation.DecelerateInterpolator;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
+import android.widget.flags.Flags;
 
 import com.android.internal.R;
 
@@ -790,7 +791,11 @@
         paint.setAntiAlias(true);
         paint.setTextAlign(Align.CENTER);
         paint.setTextSize(mTextSize);
-        paint.setTypeface(mInputText.getTypeface());
+        if (Flags.fixUnboldedTypefaceForNumberpicker()) {
+            paint.setTypeface(mInputText.getPaint().getTypeface());
+        } else {
+            paint.setTypeface(mInputText.getTypeface());
+        }
         ColorStateList colors = mInputText.getTextColors();
         int color = colors.getColorForState(ENABLED_STATE_SET, Color.WHITE);
         paint.setColor(color);
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 9fe3fd6..7c75d7b 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -5820,8 +5820,13 @@
                         mActions.forEach(action -> {
                             if (viewId == action.mViewId
                                     && action instanceof SetOnClickResponse setOnClickResponse) {
-                                setOnClickResponse.mResponse.handleViewInteraction(
-                                        player, params.handler);
+                                final RemoteResponse response = setOnClickResponse.mResponse;
+                                if (response.mFillIntent == null) {
+                                    response.mFillIntent = new Intent();
+                                }
+                                response.mFillIntent.putExtra(
+                                        "remotecompose_metadata", metadata);
+                                response.handleViewInteraction(player, params.handler);
                             }
                         });
                     });
diff --git a/core/java/android/widget/flags/flags.aconfig b/core/java/android/widget/flags/flags.aconfig
index d9dc36c..88eb043 100644
--- a/core/java/android/widget/flags/flags.aconfig
+++ b/core/java/android/widget/flags/flags.aconfig
@@ -17,3 +17,13 @@
   is_exported: true
   bug: "369480667"
 }
+
+flag {
+  name: "fix_unbolded_typeface_for_numberpicker"
+  namespace: "text"
+  description: "Use the correct bolded typeface when drawing the selector numbers"
+  bug: "318304896"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
diff --git a/core/java/android/window/flags/responsible_apis.aconfig b/core/java/android/window/flags/responsible_apis.aconfig
index d5ba32c..4b5adfc 100644
--- a/core/java/android/window/flags/responsible_apis.aconfig
+++ b/core/java/android/window/flags/responsible_apis.aconfig
@@ -75,4 +75,9 @@
     bug: "362575865"
 }
 
-
+flag {
+    name: "bal_strict_mode_grace_period"
+    namespace: "responsible_apis"
+    description: "Strict mode violation triggered by grace period usage"
+    bug: "384807495"
+}
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index f346544..7eabd17 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -441,4 +441,12 @@
     metadata {
         purpose: PURPOSE_BUGFIX
     }
-}
\ No newline at end of file
+}
+
+flag {
+    name: "port_window_size_animation"
+    namespace: "systemui"
+    description: "Port window-resize animation from legacy to shell"
+    bug: "384976265"
+}
+
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index b8f7a3d..5d55418 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -18,6 +18,9 @@
 
 import static android.os.VibrationEffect.Composition.PRIMITIVE_SPIN;
 
+import static java.lang.Math.hypot;
+import static java.lang.Math.max;
+
 import android.animation.ObjectAnimator;
 import android.animation.TimeAnimator;
 import android.annotation.SuppressLint;
@@ -26,9 +29,11 @@
 import android.content.ActivityNotFoundException;
 import android.content.ContentResolver;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
+import android.graphics.ColorSpace;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
@@ -72,7 +77,7 @@
     private static final String EGG_UNLOCK_SETTING = "egg_mode_v";
 
     private static final float MIN_WARP = 1f;
-    private static final float MAX_WARP = 10f; // after all these years
+    private static final float MAX_WARP = 16f; // must go faster
     private static final boolean FINISH_AFTER_NEXT_STAGE_LAUNCH = false;
 
     private ImageView mLogo;
@@ -201,6 +206,9 @@
         getWindow().setStatusBarColor(0);
         getWindow().getDecorView().getWindowInsetsController().hide(WindowInsets.Type.systemBars());
 
+        // This will be silently ignored on displays that don't support HDR color, which is fine
+        getWindow().setColorMode(ActivityInfo.COLOR_MODE_HDR);
+
         final ActionBar ab = getActionBar();
         if (ab != null) ab.hide();
 
@@ -364,7 +372,7 @@
                 mPressureMin = Math.min(mPressureMin, touchData.getDouble("min"));
             }
             if (touchData.has("max")) {
-                mPressureMax = Math.max(mPressureMax, touchData.getDouble("max"));
+                mPressureMax = max(mPressureMax, touchData.getDouble("max"));
             }
             if (mPressureMax >= 0) {
                 touchData.put("min", mPressureMin);
@@ -392,9 +400,11 @@
     }
 
     private static class Starfield extends Drawable {
-        private static final int NUM_STARS = 34; // Build.VERSION_CODES.UPSIDE_DOWN_CAKE
+        private static final int NUM_STARS = 128;
 
-        private static final int NUM_PLANES = 2;
+        private static final int NUM_PLANES = 4;
+
+        private static final float ROTATION = 45;
         private final float[] mStars = new float[NUM_STARS * 4];
         private float mVx, mVy;
         private long mDt = 0;
@@ -403,7 +413,7 @@
         private final Random mRng;
         private final float mSize;
 
-        private final Rect mSpace = new Rect();
+        private float mRadius = 0f;
         private float mWarp = 1f;
 
         private float mBuffer;
@@ -426,14 +436,15 @@
 
         @Override
         public void onBoundsChange(Rect bounds) {
-            mSpace.set(bounds);
             mBuffer = mSize * NUM_PLANES * 2 * MAX_WARP;
-            mSpace.inset(-(int) mBuffer, -(int) mBuffer);
-            final float w = mSpace.width();
-            final float h = mSpace.height();
+            mRadius = ((float) hypot(bounds.width(), bounds.height()) / 2f) + mBuffer;
+            // I didn't clarify this the last time, but we store both the beginning and
+            // end of each star's trail in this data structure. When we're not in warp that means
+            // that we've got each star in there twice. It's fine, we're gonna move it off-screen
             for (int i = 0; i < NUM_STARS; i++) {
-                mStars[4 * i] = mRng.nextFloat() * w;
-                mStars[4 * i + 1] = mRng.nextFloat() * h;
+                mStars[4 * i] = mRng.nextFloat() * 2 * mRadius - mRadius;
+                mStars[4 * i + 1] = mRng.nextFloat() * 2 * mRadius - mRadius;
+                // duplicate copy (for now)
                 mStars[4 * i + 2] = mStars[4 * i];
                 mStars[4 * i + 3] = mStars[4 * i + 1];
             }
@@ -452,31 +463,47 @@
 
             final boolean inWarp = mWarp > 1f;
 
-            canvas.drawColor(Color.BLACK); // 0xFF16161D);
+            final float diameter = mRadius * 2f;
+            final float triameter = mRadius * 3f;
+
+            canvas.drawColor(Color.BLACK);
+
+            final float cx = getBounds().width() / 2f;
+            final float cy = getBounds().height() / 2f;
+            canvas.translate(cx, cy);
+
+            canvas.rotate(ROTATION);
 
             if (mDt > 0 && mDt < 1000) {
                 canvas.translate(
-                        -(mBuffer) + mRng.nextFloat() * (mWarp - 1f),
-                        -(mBuffer) + mRng.nextFloat() * (mWarp - 1f)
+                        mRng.nextFloat() * (mWarp - 1f),
+                        mRng.nextFloat() * (mWarp - 1f)
                 );
-                final float w = mSpace.width();
-                final float h = mSpace.height();
                 for (int i = 0; i < NUM_STARS; i++) {
                     final int plane = (int) ((((float) i) / NUM_STARS) * NUM_PLANES) + 1;
-                    mStars[4 * i + 2] = (mStars[4 * i + 2] + dx * plane + w) % w;
-                    mStars[4 * i + 3] = (mStars[4 * i + 3] + dy * plane + h) % h;
-                    mStars[4 * i + 0] = inWarp ? mStars[4 * i + 2] - dx * mWarp * 2 * plane : -100;
-                    mStars[4 * i + 1] = inWarp ? mStars[4 * i + 3] - dy * mWarp * 2 * plane : -100;
+                    mStars[4 * i + 2] = (mStars[4 * i + 2] + dx * plane + triameter) % diameter
+                            - mRadius;
+                    mStars[4 * i + 3] = (mStars[4 * i + 3] + dy * plane + triameter) % diameter
+                            - mRadius;
+                    mStars[4 * i + 0] = inWarp ? mStars[4 * i + 2] - dx * mWarp * plane : -10000;
+                    mStars[4 * i + 1] = inWarp ? mStars[4 * i + 3] - dy * mWarp * plane : -10000;
                 }
             }
             final int slice = (mStars.length / NUM_PLANES / 4) * 4;
             for (int p = 0; p < NUM_PLANES; p++) {
+                final float value = (p + 1f) / (NUM_PLANES - 1);
+                mStarPaint.setColor(packHdrColor(value, 1.0f));
                 mStarPaint.setStrokeWidth(mSize * (p + 1));
                 if (inWarp) {
                     canvas.drawLines(mStars, p * slice, slice, mStarPaint);
                 }
                 canvas.drawPoints(mStars, p * slice, slice, mStarPaint);
             }
+
+            if (inWarp) {
+                final float frac = (mWarp - MIN_WARP) / (MAX_WARP - MIN_WARP);
+                canvas.drawColor(packHdrColor(2.0f, frac * frac));
+            }
         }
 
         @Override
@@ -497,5 +524,10 @@
         public void update(long dt) {
             mDt = dt;
         }
+
+        private static final ColorSpace sSrgbExt = ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB);
+        public static long packHdrColor(float value, float alpha) {
+            return Color.valueOf(value, value, value, alpha, sSrgbExt).pack();
+        }
     }
 }
diff --git a/core/java/com/android/internal/display/BrightnessSynchronizer.java b/core/java/com/android/internal/display/BrightnessSynchronizer.java
index a50dbb0..50f1000 100644
--- a/core/java/com/android/internal/display/BrightnessSynchronizer.java
+++ b/core/java/com/android/internal/display/BrightnessSynchronizer.java
@@ -601,7 +601,7 @@
             cr.registerContentObserver(BRIGHTNESS_URI, false,
                     createBrightnessContentObserver(handler), UserHandle.USER_ALL);
             mDisplayManager.registerDisplayListener(mListener, handler, /* eventFlags */ 0,
-                    DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS);
+                    DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS);
             mIsObserving = true;
         }
     }
diff --git a/core/java/com/android/internal/policy/KeyInterceptionInfo.java b/core/java/com/android/internal/policy/KeyInterceptionInfo.java
index b20f6d2..fed8fe3 100644
--- a/core/java/com/android/internal/policy/KeyInterceptionInfo.java
+++ b/core/java/com/android/internal/policy/KeyInterceptionInfo.java
@@ -27,11 +27,13 @@
     // Debug friendly name to help identify the window
     public final String windowTitle;
     public final int windowOwnerUid;
+    public final int inputFeaturesFlags;
 
-    public KeyInterceptionInfo(int type, int flags, String title, int uid) {
+    public KeyInterceptionInfo(int type, int flags, String title, int uid, int inputFeaturesFlags) {
         layoutParamsType = type;
         layoutParamsPrivateFlags = flags;
         windowTitle = title;
         windowOwnerUid = uid;
+        this.inputFeaturesFlags = inputFeaturesFlags;
     }
 }
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index efbf887..9380d99 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -149,6 +149,15 @@
     + "permission.WRITE_SECURE_SETTINGS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL})")
     oneway void onImeSwitchButtonClickFromSystem(int displayId);
 
+    /**
+     * A test API for CTS to check whether the IME Switcher button should be shown when the IME
+     * is shown.
+     */
+    @EnforcePermission("TEST_INPUT_METHOD")
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
+            + "android.Manifest.permission.TEST_INPUT_METHOD)")
+    boolean shouldShowImeSwitcherButtonForTest();
+
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
             + "android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)")
     @nullable InputMethodSubtype getCurrentInputMethodSubtype(int userId);
diff --git a/core/java/com/android/internal/widget/NotificationExpandButton.java b/core/java/com/android/internal/widget/NotificationExpandButton.java
index d4dd1e7..751cfde 100644
--- a/core/java/com/android/internal/widget/NotificationExpandButton.java
+++ b/core/java/com/android/internal/widget/NotificationExpandButton.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.widget;
 
+import static android.app.Flags.notificationsRedesignTemplates;
+
 import android.annotation.ColorInt;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -130,10 +132,18 @@
         int drawableId;
         int contentDescriptionId;
         if (mExpanded) {
-            drawableId = R.drawable.ic_collapse_notification;
+            if (notificationsRedesignTemplates()) {
+                drawableId = R.drawable.ic_notification_2025_collapse;
+            } else {
+                drawableId = R.drawable.ic_collapse_notification;
+            }
             contentDescriptionId = R.string.expand_button_content_description_expanded;
         } else {
-            drawableId = R.drawable.ic_expand_notification;
+            if (notificationsRedesignTemplates()) {
+                drawableId = R.drawable.ic_notification_2025_expand;
+            } else {
+                drawableId = R.drawable.ic_expand_notification;
+            }
             contentDescriptionId = R.string.expand_button_content_description_collapsed;
         }
         setContentDescription(mContext.getText(contentDescriptionId));
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
index fb560a5..26b0d11 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
@@ -62,7 +62,7 @@
 
     // We also keep a more fine-grained BUILD number, exposed as
     // ID_API_LEVEL = DOCUMENT_API_LEVEL + BUILD
-    static final float BUILD = 0.1f;
+    static final float BUILD = 0.2f;
 
     @NonNull ArrayList<Operation> mOperations = new ArrayList<>();
 
@@ -1058,7 +1058,7 @@
      * @param theme the theme we want to use for this document.
      */
     public void paint(@NonNull RemoteContext context, int theme) {
-        context.getLastOpCount();
+        context.clearLastOpCount();
         context.getPaintContext().clearNeedsRepaint();
         context.loadFloat(RemoteContext.ID_DENSITY, context.getDensity());
         context.mMode = RemoteContext.ContextMode.UNSET;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
index cd26198..43f8ea7d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
@@ -528,6 +528,7 @@
 
     public void setContext(@NonNull RemoteContext context) {
         mRemoteContext = context;
+        mRemoteContext.clearLastOpCount();
     }
 
     public void updateObject(int id, @NonNull Object value) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
index ec33663..23c3628 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
@@ -743,4 +743,9 @@
         mOpCount = 0;
         return count;
     }
+
+    /** Explicitly clear the operation counter */
+    public void clearLastOpCount() {
+        mOpCount = 0;
+    }
 }
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index c901ee1..cf81ba1 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -106,6 +106,7 @@
         optional SettingProto display_daltonizer_saturation_level = 58 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto accessibility_key_gesture_targets = 59 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto hct_rect_prompt_status = 60 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto em_value = 61 [ (android.privacy).dest = DEST_AUTOMATIC ];
 
     }
     optional Accessibility accessibility = 2;
diff --git a/core/res/res/drawable-nodpi/platlogo.xml b/core/res/res/drawable-nodpi/platlogo.xml
index 822aa22..7432796 100644
--- a/core/res/res/drawable-nodpi/platlogo.xml
+++ b/core/res/res/drawable-nodpi/platlogo.xml
@@ -1,5 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
-Copyright (C) 2021 The Android Open Source Project
+Copyright (C) 2024 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,97 +19,129 @@
     android:height="512dp"
     android:viewportWidth="512"
     android:viewportHeight="512">
-  <!-- space -->
   <path
-      android:pathData="M256,446.36C229.63,446.36 212.19,428.06 194.8,397.94C177.41,367.82 91.54,219.08 74.14,188.96C56.75,158.84 49.63,134.59 62.81,111.75C76,88.91 100.56,82.95 135.35,82.95C170.13,82.95 341.87,82.95 376.65,82.95C411.44,82.95 436,88.91 449.19,111.75C462.37,134.59 455.25,158.84 437.86,188.96C420.46,219.08 334.59,367.82 317.2,397.94C299.81,428.06 282.37,446.36 256,446.36H256Z"
-      android:fillColor="#202124"/>
-  <group>
-    <clip-path
-        android:pathData="M256,446.36C229.63,446.36 212.19,428.06 194.8,397.94C177.41,367.82 91.54,219.08 74.14,188.96C56.75,158.84 49.63,134.59 62.81,111.75C76,88.91 100.56,82.95 135.35,82.95C170.13,82.95 341.87,82.95 376.65,82.95C411.44,82.95 436,88.91 449.19,111.75C462.37,134.59 455.25,158.84 437.86,188.96C420.46,219.08 334.59,367.82 317.2,397.94C299.81,428.06 282.37,446.36 256,446.36H256Z"/>
-    <!-- thrust plume -->
-    <path
-        android:pathData="M253,153C249.82,187.48 225.67,262.17 167.98,285.04C110.3,307.92 73.96,318.12 63,320.36L256,399L449,320.36C438.04,318.12 401.7,307.92 344.02,285.04C286.33,262.17 262.18,187.48 259,153H256H253Z"
-        android:fillColor="#C6FF00"
-        android:fillType="evenOdd"/>
-    <path
-        android:pathData="M253,153C251.5,187.42 241.7,261.98 214.5,284.82C187.3,307.65 170.17,317.84 165,320.08L256,398.58L347,320.08C341.83,317.84 324.7,307.65 297.5,284.82C270.3,261.98 260.5,187.42 259,153H256H253Z"
-        android:fillColor="#ffffff"
-        android:fillType="evenOdd"/>
-    <path
-        android:pathData="M256,153m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0"
-        android:fillColor="#ffffff"/>
-    <!-- android head and body -->
-    <path
-        android:pathData="M151,350h199v104h-199z"
-        android:fillColor="#5F6368"/>
-    <path
-        android:pathData="M358.42,350.44C358.36,350.02 358.29,349.6 358.22,349.18C357.8,346.6 357.27,344.04 356.65,341.52C355.57,337.12 354.21,332.82 352.59,328.66C351.22,325.13 349.66,321.7 347.93,318.38C345.7,314.11 343.18,310.01 340.41,306.11C337.01,301.34 333.21,296.86 329.06,292.74C327.32,291.01 325.52,289.34 323.65,287.73C319.62,284.26 315.32,281.09 310.78,278.26C310.82,278.19 310.85,278.12 310.89,278.05C312.97,274.46 315.05,270.88 317.13,267.29C319.17,263.78 321.2,260.28 323.23,256.77C324.69,254.26 326.15,251.74 327.61,249.22C327.95,248.62 328.22,248.01 328.43,247.37C329,245.61 329.02,243.76 328.57,242.03C328.45,241.61 328.31,241.19 328.14,240.78C327.97,240.38 327.77,239.98 327.54,239.6C326.76,238.29 325.65,237.16 324.26,236.33C323.02,235.6 321.64,235.16 320.23,235.03C319.64,234.98 319.04,234.99 318.45,235.05C317.96,235.1 317.47,235.19 316.99,235.32C315.26,235.77 313.67,236.72 312.42,238.08C311.98,238.57 311.58,239.12 311.23,239.71C309.77,242.23 308.31,244.75 306.85,247.27L300.76,257.78C298.68,261.37 296.6,264.96 294.52,268.55C294.29,268.94 294.06,269.33 293.83,269.73C293.52,269.6 293.21,269.48 292.89,269.36C281.43,264.99 269,262.6 256.01,262.6C255.65,262.6 255.3,262.6 254.94,262.6C243.39,262.72 232.29,264.73 221.93,268.33C220.73,268.75 219.55,269.19 218.38,269.65C218.16,269.29 217.95,268.92 217.74,268.55C215.66,264.96 213.58,261.38 211.5,257.79C209.47,254.28 207.43,250.78 205.4,247.27C203.94,244.76 202.48,242.23 201.02,239.72C200.68,239.12 200.28,238.58 199.83,238.09C198.59,236.72 196.99,235.78 195.27,235.32C194.79,235.2 194.3,235.1 193.81,235.05C193.22,234.99 192.62,234.99 192.03,235.04C190.61,235.16 189.23,235.6 188,236.34C186.6,237.16 185.5,238.3 184.71,239.6C184.49,239.99 184.29,240.38 184.12,240.79C183.95,241.2 183.8,241.61 183.69,242.04C183.23,243.76 183.26,245.62 183.82,247.38C184.03,248.01 184.3,248.63 184.65,249.23C186.11,251.74 187.57,254.26 189.02,256.78C191.06,260.28 193.09,263.79 195.12,267.29C197.2,270.88 199.28,274.47 201.36,278.06C201.38,278.09 201.4,278.12 201.41,278.15C197.22,280.76 193.23,283.64 189.47,286.8C187.21,288.69 185.04,290.68 182.96,292.75C178.81,296.87 175.01,301.35 171.6,306.12C168.82,310.02 166.31,314.11 164.09,318.39C162.35,321.71 160.79,325.14 159.42,328.67C157.8,332.83 156.44,337.13 155.36,341.53C154.75,344.05 154.22,346.6 153.79,349.19C153.72,349.61 153.66,350.03 153.59,350.45C153.36,351.95 153.16,353.46 153,354.98L359,354.98C358.84,353.46 358.64,351.95 358.41,350.45L358.42,350.44Z"
-        android:fillColor="#5F6368"/>
-  </group>
-  <!-- stars -->
-  <group>
-    <path
-        android:pathData="M131.04,134.34H127V138.38H131.04V134.34Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M167.04,256H163V260.04H167.04V256Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M373.49,127H369.45V131.04H373.49V127Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M292.04,226H288V230.04H292.04V226Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M319.04,186.91H315V190.95H319.04V186.91Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M355.04,222H351V226.04H355.04V222Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M192.04,136H188V140.04H192.04V136Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M336.08,196H328V204.08H336.08V196Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M222.04,212H218V216.04H222.04V212Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M163.08,175H155V183.08H163.08V175Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M211.08,143H203V151.08H211.08V143Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M369.08,204H361V212.08H369.08V204Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M169.21,204.34H161.13V212.42H169.21V204.34Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M383.04,160.07H374.95V168.15H383.04V160.07Z"
-        android:fillColor="#ffffff"/>
-    <path
-        android:pathData="M192.08,183H184V191.08H192.08V183Z"
-        android:fillColor="#ffffff"/>
-  </group>
-  <!-- patch frame -->
-  <path
-      android:pathData="M256,446.36C229.63,446.36 212.19,428.06 194.8,397.94C177.41,367.82 91.54,219.08 74.14,188.96C56.75,158.84 49.63,134.59 62.81,111.75C76,88.91 100.56,82.95 135.35,82.95C170.13,82.95 341.87,82.95 376.65,82.95C411.44,82.95 436,88.91 449.19,111.75C462.37,134.59 455.25,158.84 437.86,188.96C420.46,219.08 334.59,367.82 317.2,397.94C299.81,428.06 282.37,446.36 256,446.36H256Z"
+      android:pathData="M127,58.5L385,58.5A68.5,68.5 0,0 1,453.5 127L453.5,385A68.5,68.5 0,0 1,385 453.5L127,453.5A68.5,68.5 0,0 1,58.5 385L58.5,127A68.5,68.5 0,0 1,127 58.5z"
       android:strokeWidth="55"
+      android:fillColor="#1D2126"
+      android:strokeColor="#4285F4"/>
+  <path
+      android:pathData="M152.157,72C149.469,72 148.125,72 148.125,72C148.125,72 148.581,70.818 149.493,68.454L157.269,48.222C157.773,46.89 158.025,46.224 158.025,46.224C158.025,46.224 158.913,46.224 160.689,46.224C162.405,46.224 163.263,46.224 163.263,46.224C163.263,46.224 163.521,46.884 164.037,48.204L171.759,68.418C172.683,70.806 173.145,72 173.145,72C173.145,72 171.831,72 169.203,72C167.643,72 166.863,72 166.863,72C166.863,72 166.683,71.448 166.323,70.344L161.481,56.376L160.617,53.496H160.509L159.645,56.358L154.767,70.308C154.419,71.436 154.245,72 154.245,72C154.245,72 153.549,72 152.157,72ZM152.949,66.996L154.479,62.874H166.287L167.871,66.996H152.949ZM186.631,72C184.759,72 183.823,72 183.823,72C183.823,72 183.823,71.148 183.823,69.444V49.59C183.823,47.346 183.823,46.224 183.823,46.224C183.823,46.224 185.065,46.224 187.549,46.224C189.001,46.224 189.727,46.224 189.727,46.224C189.727,46.224 190.021,46.686 190.609,47.61L199.807,62.046H199.915L199.807,58.05V48.708C199.807,47.052 199.807,46.224 199.807,46.224C199.807,46.224 200.737,46.224 202.597,46.224C204.469,46.224 205.405,46.224 205.405,46.224C205.405,46.224 205.405,47.052 205.405,48.708V69.012C205.405,71.004 205.405,72 205.405,72C205.405,72 204.307,72 202.111,72C200.839,72 200.203,72 200.203,72C200.203,72 199.945,71.604 199.429,70.812L189.421,55.53H189.295L189.421,59.508V69.444C189.421,71.148 189.421,72 189.421,72C189.421,72 188.491,72 186.631,72ZM221.683,72C219.559,72 218.497,72 218.497,72C218.497,72 218.497,70.932 218.497,68.796V49.41C218.497,47.286 218.497,46.224 218.497,46.224C218.497,46.224 219.559,46.224 221.683,46.224H227.677C231.613,46.224 234.787,47.406 237.199,49.77C239.611,52.122 240.817,55.23 240.817,59.094C240.817,62.982 239.611,66.108 237.199,68.472C234.787,70.824 231.613,72 227.677,72H221.683ZM224.293,66.852H227.353C229.681,66.876 231.523,66.21 232.879,64.854C234.247,63.486 234.931,61.584 234.931,59.148C234.931,56.736 234.253,54.864 232.897,53.532C231.541,52.2 229.693,51.534 227.353,51.534H224.293V66.852ZM255.401,72C253.469,72 252.503,72 252.503,72C252.503,72 252.503,71.13 252.503,69.39V49.41C252.503,47.286 252.503,46.224 252.503,46.224C252.503,46.224 253.565,46.224 255.689,46.224H262.763C265.319,46.224 267.467,46.98 269.207,48.492C270.959,50.004 271.835,52.02 271.835,54.54C271.835,56.904 271.001,58.848 269.333,60.372C267.677,61.884 265.517,62.64 262.853,62.64H254.915V58.482H262.205C263.285,58.482 264.191,58.146 264.923,57.474C265.667,56.79 266.039,55.896 266.039,54.792C266.039,53.796 265.679,52.962 264.959,52.29C264.251,51.606 263.381,51.264 262.349,51.264H258.299V69.39C258.299,71.13 258.299,72 258.299,72C258.299,72 257.333,72 255.401,72ZM268.703,72C267.551,72 266.975,72 266.975,72C266.975,72 266.759,71.664 266.327,70.992L259.487,60.444L265.607,60.228L270.917,68.004C272.765,70.668 273.689,72 273.689,72C273.689,72 272.027,72 268.703,72ZM295.491,72.594C291.771,72.594 288.603,71.346 285.987,68.85C283.383,66.342 282.081,63.09 282.081,59.094C282.081,55.086 283.389,51.84 286.005,49.356C288.633,46.872 291.789,45.63 295.473,45.63C299.157,45.63 302.313,46.89 304.941,49.41C307.569,51.918 308.883,55.146 308.883,59.094C308.883,63.018 307.575,66.252 304.959,68.796C302.355,71.328 299.199,72.594 295.491,72.594ZM295.473,66.996C297.645,66.996 299.451,66.252 300.891,64.764C302.343,63.264 303.069,61.374 303.069,59.094C303.069,56.79 302.343,54.906 300.891,53.442C299.439,51.966 297.633,51.228 295.473,51.228C293.337,51.228 291.537,51.966 290.073,53.442C288.621,54.918 287.895,56.802 287.895,59.094C287.895,61.386 288.615,63.276 290.055,64.764C291.507,66.252 293.313,66.996 295.473,66.996ZM323.519,72C321.563,72 320.585,72 320.585,72C320.585,72 320.585,71.118 320.585,69.354V48.87C320.585,47.106 320.585,46.224 320.585,46.224C320.585,46.224 321.563,46.224 323.519,46.224C325.475,46.224 326.453,46.224 326.453,46.224C326.453,46.224 326.453,47.106 326.453,48.87V69.354C326.453,71.118 326.453,72 326.453,72C326.453,72 325.475,72 323.519,72ZM342.73,72C340.606,72 339.544,72 339.544,72C339.544,72 339.544,70.932 339.544,68.796V49.41C339.544,47.286 339.544,46.224 339.544,46.224C339.544,46.224 340.606,46.224 342.73,46.224H348.724C352.66,46.224 355.834,47.406 358.246,49.77C360.658,52.122 361.864,55.23 361.864,59.094C361.864,62.982 360.658,66.108 358.246,68.472C355.834,70.824 352.66,72 348.724,72H342.73ZM345.34,66.852H348.4C350.728,66.876 352.57,66.21 353.926,64.854C355.294,63.486 355.978,61.584 355.978,59.148C355.978,56.736 355.3,54.864 353.944,53.532C352.588,52.2 350.74,51.534 348.4,51.534H345.34V66.852Z"
+      android:fillColor="#ffffff"/>
+  <path
+      android:pathData="M196.971,198.17H257.84L196.971,259.04V198.17Z"
+      android:fillColor="#1F8E3D"/>
+  <path
+      android:pathData="M318.709,319.909L257.84,319.909L318.709,259.04L318.709,319.909Z"
+      android:fillColor="#1F8E3D"/>
+  <path
+      android:pathData="M318.709,198.17L318.709,259.04L257.84,198.17L318.709,198.17Z"
+      android:fillColor="#34A853"/>
+  <path
+      android:pathData="M196.971,319.909L196.971,259.04L257.84,319.909L196.971,319.909Z"
+      android:fillColor="#34A853"/>
+  <path
+      android:pathData="M257.84,259.04L196.971,259.04L257.84,198.171L257.84,259.04Z"
+      android:fillColor="#34A853"/>
+  <path
+      android:pathData="M257.84,198.17L196.971,198.17L257.84,137.301L257.84,198.17Z"
+      android:fillColor="#34A853"/>
+  <path
+      android:pathData="M257.84,319.909L318.709,319.909L257.84,380.778L257.84,319.909Z"
+      android:fillColor="#34A853"/>
+  <path
+      android:pathData="M257.84,259.04L318.709,259.04L257.84,319.91L257.84,259.04Z"
+      android:fillColor="#34A853"/>
+  <path
+      android:pathData="M318.709,259.04L379.579,259.04L318.709,319.91L318.709,259.04Z"
+      android:fillColor="#34A853"/>
+  <path
+      android:pathData="M196.971,259.04L136.101,259.04L196.971,198.171L196.971,259.04Z"
+      android:fillColor="#34A853"/>
+  <path
+      android:pathData="M257.84,259.04L257.84,198.171L318.709,259.04L257.84,259.04Z"
+      android:fillColor="#1F8E3D"/>
+  <path
+      android:pathData="M257.84,198.17L257.84,137.301L318.709,198.17L257.84,198.17Z"
+      android:fillColor="#1F8E3D"/>
+  <path
+      android:pathData="M257.84,319.909L257.84,380.778L196.971,319.909L257.84,319.909Z"
+      android:fillColor="#1F8E3D"/>
+  <path
+      android:pathData="M318.709,259.04L318.709,198.171L379.579,259.04L318.709,259.04Z"
+      android:fillColor="#1F8E3D"/>
+  <path
+      android:pathData="M196.971,259.04L196.971,319.91L136.101,259.04L196.971,259.04Z"
+      android:fillColor="#1F8E3D"/>
+  <path
+      android:pathData="M257.84,259.04L257.84,319.91L196.971,259.04L257.84,259.04Z"
+      android:fillColor="#1F8E3D"/>
+  <path
+      android:pathData="M342.409,405.074C340.766,405.074 339.348,404.477 338.153,403.282C336.989,402.088 336.406,400.654 336.406,398.982V355.485L328.567,361.129C327.462,361.935 326.222,362.219 324.849,361.98C323.475,361.741 322.385,361.054 321.579,359.919C320.772,358.785 320.488,357.53 320.727,356.157C320.996,354.753 321.683,353.633 322.788,352.797L339.497,340.881C339.915,340.582 340.363,340.314 340.841,340.075C341.319,339.806 341.961,339.671 342.767,339.671C344.35,339.671 345.679,340.239 346.754,341.374C347.859,342.479 348.412,343.852 348.412,345.495V398.982C348.412,400.654 347.814,402.088 346.62,403.282C345.455,404.477 344.051,405.074 342.409,405.074ZM382.377,405.522C375.449,405.522 369.804,403.447 365.444,399.296C361.114,395.144 358.949,389.873 358.949,383.482C358.949,379.122 359.919,375.046 361.86,371.253C363.831,367.46 366.534,363.339 369.969,358.889L382.646,342.538C383.572,341.344 384.766,340.627 386.23,340.388C387.723,340.149 389.082,340.448 390.306,341.284C391.68,342.27 392.486,343.554 392.725,345.137C392.964,346.719 392.546,348.153 391.471,349.437L383.452,359.651C382.228,361.174 379.719,363.309 375.926,366.057C372.164,368.804 369.595,374.553 368.221,383.303L361.726,383.258C362.652,376.21 365.504,371.029 370.282,367.714C375.09,364.399 380.272,362.742 385.826,362.742C391.322,362.742 396.01,364.653 399.893,368.476C403.775,372.268 405.716,377.211 405.716,383.303C405.716,389.724 403.521,395.04 399.131,399.251C394.771,403.432 389.186,405.522 382.377,405.522ZM382.332,395.04C385.826,395.04 388.693,393.965 390.933,391.815C393.203,389.664 394.338,386.902 394.338,383.527C394.338,380.212 393.203,377.48 390.933,375.329C388.693,373.149 385.856,372.059 382.422,372.059C378.958,372.059 376.076,373.149 373.776,375.329C371.507,377.48 370.372,380.227 370.372,383.572C370.372,386.887 371.492,389.634 373.731,391.815C376.001,393.965 378.868,395.04 382.332,395.04Z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M265.087,135.953L380.927,251.793A10.249,10.249 90,0 1,380.927 266.287L265.087,382.126A10.249,10.249 90,0 1,250.593 382.126L134.753,266.287A10.249,10.249 0,0 1,134.753 251.793L250.593,135.953A10.249,10.249 90,0 1,265.087 135.953z"
+      android:strokeWidth="14.3349"
       android:fillColor="#00000000"
-      android:strokeColor="#34A853"/>
-  <!-- text: ANDROID -->
+      android:strokeColor="#5F6368"/>
   <path
-      android:pathData="M170.11,92.71C170.97,94.9 171.41,96 171.41,96C171.41,96 170.37,96 168.29,96C166.22,96 165.18,96 165.18,96C165.18,96 164.93,95.27 164.42,93.82L159.71,80.63L158.82,77.75H158.61L157.82,80.63L153.28,93.82C152.82,95.27 152.6,96 152.6,96C152.6,96 151.54,96 149.43,96C147.33,96 146.28,96 146.28,96C146.28,96 146.7,94.89 147.56,92.67L155.21,72.87C155.89,71.07 156.23,70.17 156.23,70.17C156.23,70.17 157.06,70.17 158.72,70.17C160.52,70.17 161.42,70.17 161.42,70.17C161.42,70.17 161.76,71.07 162.46,72.87L170.11,92.71ZM166.04,91.12H158.64V86.91H164.42L166.04,91.12ZM158.64,91.12H151.08L152.63,86.91H158.64V91.12ZM203.85,93.46C203.85,95.15 203.85,96 203.85,96C203.85,96 202.95,96 201.15,96C199.38,96 198.5,96 198.5,96C198.5,96 198.03,95.26 197.08,93.79L188.08,79.75H187.88L188.01,83.45V93.25C188.01,95.08 188.01,96 188.01,96C188.01,96 187.03,96 185.09,96C183.15,96 182.17,96 182.17,96C182.17,96 182.17,95.08 182.17,93.25L182.16,73.9C182.16,71.45 182.16,70.22 182.16,70.22C182.16,70.22 183.19,70.22 185.25,70.22C187.24,70.22 188.24,70.22 188.24,70.22C188.24,70.22 188.7,70.96 189.63,72.42L198.16,85.85H198.36L198.21,82.09V72.89C198.21,71.11 198.21,70.22 198.21,70.22C198.21,70.22 199.15,70.22 201.04,70.22C202.91,70.22 203.85,70.22 203.85,70.22C203.85,70.22 203.85,71.11 203.85,72.89V93.46ZM226.52,96H220.17C218.24,96 217.27,96 217.27,96C217.27,96 217.27,95.02 217.27,93.05V73.19C217.27,71.21 217.27,70.22 217.27,70.22C217.27,70.22 218.24,70.22 220.17,70.22H226.52C230.46,70.22 233.63,71.41 236.03,73.77C238.43,76.12 239.63,79.23 239.63,83.09C239.63,86.98 238.43,90.11 236.03,92.47C233.63,94.82 230.46,96 226.52,96ZM223.17,75.64V90.74H226.18C228.46,90.77 230.27,90.11 231.62,88.78C232.96,87.44 233.63,85.57 233.63,83.17C233.63,80.78 232.96,78.93 231.62,77.62C230.28,76.3 228.47,75.64 226.18,75.64H223.17ZM257.51,93.23C257.51,95.08 257.51,96 257.51,96C257.51,96 256.54,96 254.6,96C252.66,96 251.7,96 251.7,96C251.7,96 251.7,95.09 251.7,93.26V73.19C251.7,71.21 251.7,70.22 251.7,70.22C251.7,70.22 252.66,70.22 254.6,70.22H261.89C264.44,70.22 266.6,70.98 268.35,72.49C270.1,74 270.98,76.03 270.98,78.56C270.98,80.9 270.14,82.83 268.47,84.35C266.81,85.87 264.65,86.62 262.01,86.62H254.02V82.41H261.33C262.4,82.41 263.29,82.08 264.01,81.42C264.73,80.75 265.09,79.88 265.09,78.81C265.09,77.84 264.74,77.03 264.05,76.38C263.35,75.72 262.49,75.39 261.47,75.39H257.51V93.23ZM264.77,93.82L258.66,84.46L264.8,84.25L271.23,93.62C272.37,95.21 272.94,96 272.94,96C272.94,96 271.82,96 269.57,96C267.3,96 266.17,96 266.17,96C266.17,96 265.7,95.27 264.77,93.82ZM296.04,96.58C292.33,96.58 289.16,95.33 286.52,92.85C283.89,90.37 282.58,87.11 282.58,83.09C282.58,79.07 283.9,75.83 286.54,73.36C289.19,70.88 292.36,69.65 296.04,69.65C299.71,69.65 302.87,70.9 305.51,73.41C308.16,75.91 309.49,79.13 309.49,83.09C309.49,87.03 308.17,90.26 305.53,92.8C302.9,95.32 299.74,96.58 296.04,96.58ZM296.04,90.83C298.19,90.83 299.98,90.1 301.41,88.64C302.85,87.17 303.57,85.33 303.57,83.09C303.57,80.84 302.84,78.99 301.39,77.55C299.95,76.11 298.17,75.39 296.04,75.39C293.92,75.39 292.13,76.12 290.68,77.57C289.24,79.01 288.52,80.85 288.52,83.09C288.52,85.35 289.23,87.2 290.66,88.66C292.1,90.11 293.89,90.83 296.04,90.83ZM327.64,93.05C327.64,95.02 327.64,96 327.64,96C327.64,96 326.63,96 324.61,96C322.59,96 321.57,96 321.57,96C321.57,96 321.57,95.02 321.57,93.05V73.18C321.57,71.21 321.57,70.22 321.57,70.22C321.57,70.22 322.58,70.22 324.6,70.22C326.63,70.22 327.64,70.22 327.64,70.22C327.64,70.22 327.64,71.21 327.64,73.18V93.05ZM350.31,96H343.96C342.03,96 341.06,96 341.06,96C341.06,96 341.06,95.02 341.06,93.05V73.19C341.06,71.21 341.06,70.22 341.06,70.22C341.06,70.22 342.03,70.22 343.96,70.22H350.31C354.25,70.22 357.42,71.41 359.82,73.77C362.22,76.12 363.42,79.23 363.42,83.09C363.42,86.98 362.22,90.11 359.82,92.47C357.42,94.82 354.25,96 350.31,96ZM346.96,75.64V90.74H349.97C352.25,90.77 354.06,90.11 355.41,88.78C356.75,87.44 357.42,85.57 357.42,83.17C357.42,80.78 356.75,78.93 355.41,77.62C354.07,76.3 352.26,75.64 349.97,75.64H346.96Z"
-      android:fillColor="#E9F3EB"/>
-  <!-- text: 15 -->
+      android:pathData="M172.353,318.422C172.818,317.837 172.778,316.987 172.249,316.459V316.459C171.631,315.841 170.606,315.905 170.06,316.587C133.391,362.417 114.184,398.637 123.921,408.374C138.509,422.962 212.535,372.586 289.264,295.857C296.618,288.503 303.729,281.175 310.565,273.921C311.305,273.135 311.286,271.903 310.522,271.139L306.337,266.954C305.538,266.156 304.238,266.176 303.463,266.998C296.672,274.202 289.587,281.503 282.248,288.842C212.272,358.818 145.748,405.747 133.662,393.66C126.026,386.024 141.946,356.659 172.353,318.422Z"
+      android:fillColor="#C6FF00"
+      android:fillType="evenOdd"/>
   <path
-      android:pathData="M236.59,363.25C236.59,365.75 236.59,367 236.59,367C236.59,367 235.32,367 232.79,367C230.32,367 229.09,367 229.09,367C229.09,367 229.09,365.75 229.09,363.25V305.85L216.64,314.75C215,315.92 214.19,316.5 214.19,316.5C214.19,316.5 213.54,315.5 212.24,313.5C210.97,311.6 210.34,310.65 210.34,310.65C210.34,310.62 211.2,309.98 212.94,308.75L227.64,298.2C230.3,296.23 231.64,295.25 231.64,295.25C231.64,295.25 232.1,295.25 233.04,295.25C235.4,295.25 236.59,295.25 236.59,295.25C236.59,295.25 236.59,296.47 236.59,298.9V363.25ZM247.09,330L251.19,299C251.52,296.6 251.69,295.4 251.69,295.4C251.69,295.4 252.77,295.4 254.94,295.4H284.54C286.97,295.4 288.19,295.4 288.19,295.4C288.19,295.4 288.19,296.58 288.19,298.95C288.19,301.48 288.19,302.75 288.19,302.75C288.19,302.75 286.97,302.75 284.54,302.75H257.49L254.19,327.45L254.39,327.5C256.09,325.77 258.27,324.38 260.94,323.35C263.61,322.28 266.65,321.75 270.09,321.75C276.55,321.75 281.99,323.97 286.39,328.4C290.79,332.8 292.99,338.32 292.99,344.95C292.99,351.75 290.8,357.4 286.44,361.9C282.11,366.37 276.42,368.6 269.39,368.6C263.09,368.6 257.77,367 253.44,363.8C249.1,360.6 246.26,356.85 244.89,352.55C244.26,350.32 243.94,349.2 243.94,349.2C243.94,349.2 245.09,348.77 247.39,347.9C249.79,347 250.99,346.55 250.99,346.55C250.99,346.55 251.3,347.73 251.94,350.1C252.8,352.73 254.71,355.27 257.64,357.7C260.61,360.13 264.44,361.35 269.14,361.35C274.27,361.35 278.24,359.88 281.04,356.95C283.84,353.98 285.24,350.03 285.24,345.1C285.24,340.37 283.67,336.52 280.54,333.55C277.44,330.58 273.4,329.1 268.44,329.1C265.47,329.1 262.95,329.52 260.89,330.35C258.82,331.15 257.09,332.28 255.69,333.75C254.39,335.25 253.74,336 253.74,336C253.74,336 252.55,335.52 250.19,334.55C247.85,333.62 246.69,333.15 246.69,333.15C246.69,333.15 246.82,332.1 247.09,330Z"
-      android:fillColor="#E9F3EB"/>
-  <!-- spacecraft -->
+      android:pathData="M347.267,248.089C348.867,247.66 350.512,248.61 350.941,250.21C351.37,251.81 350.42,253.455 348.82,253.884L347.267,248.089ZM348.82,253.884L321.452,261.217L319.899,255.422L347.267,248.089L348.82,253.884Z"
+      android:fillColor="#000000"/>
   <path
-      android:pathData="M256.12,121C249.43,121 244,126.27 244,132.77V147.29C244,148.54 245.02,149.56 246.27,149.56C247.53,149.56 248.55,148.55 248.55,147.29V143.38C248.55,140.87 250.58,138.83 253.09,138.83H259.15C261.66,138.83 263.7,140.87 263.7,143.38V147.29C263.7,148.54 264.71,149.56 265.97,149.56C267.23,149.56 268.24,148.55 268.24,147.29V132.77C268.24,126.27 262.82,121 256.12,121H256.12Z"
-      android:fillColor="#E9F3EB"/>
+      android:pathData="M325.111,230.175C325.54,228.575 327.185,227.625 328.785,228.054C330.386,228.483 331.335,230.128 330.907,231.728L325.111,230.175ZM330.907,231.728L323.573,259.096L317.778,257.543L325.111,230.175L330.907,231.728Z"
+      android:fillColor="#000000"/>
+  <path
+      android:pathData="M335.665,242.984C327.494,234.813 314.434,234.623 306.498,242.559L288.774,260.283C287.243,261.814 287.243,264.3 288.774,265.831C290.306,267.363 292.791,267.363 294.323,265.831L299.1,261.054C302.165,257.989 307.132,257.989 310.197,261.054L317.595,268.452C320.66,271.517 320.66,276.484 317.595,279.549L312.818,284.326C311.286,285.858 311.286,288.344 312.818,289.875C314.349,291.406 316.835,291.406 318.366,289.875L336.09,272.151C344.026,264.215 343.836,251.155 335.665,242.984Z"
+      android:fillColor="#000000"/>
+  <path
+      android:pathData="M123.071,117.004l7.071,7.071l-7.071,7.071l-7.071,-7.071z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M108.071,332l7.071,7.071l-7.071,7.071l-7.071,-7.071z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M120.607,299l10.607,10.607l-10.607,10.607l-10.607,-10.607z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M123.071,183.435l7.071,7.071l-7.071,7.071l-7.071,-7.071z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M174.606,137l10.607,10.607l-10.607,10.607l-10.607,-10.607z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M145.214,139.149l7.071,7.071l-7.071,7.071l-7.071,-7.071z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M215.607,385l10.607,10.607l-10.607,10.607l-10.607,-10.607z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M227.071,110l7.071,7.071l-7.071,7.071l-7.071,-7.071z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M400.569,124.075l-7.071,7.071l-7.071,-7.071l7.071,-7.071z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M388.213,149.606l-10.607,10.607l-10.607,-10.607l10.607,-10.607z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M331.142,121.071l-7.071,7.071l-7.071,-7.071l7.071,-7.071z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M338.142,153.071l-7.071,7.071l-7.071,-7.071l7.071,-7.071z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M374.142,320.071l-7.071,7.071l-7.071,-7.071l7.071,-7.071z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M307.213,109.607l-10.607,10.607l-10.607,-10.607l10.607,-10.607z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M181.142,353.071l-7.071,7.071l-7.071,-7.071l7.071,-7.071z"
+      android:fillColor="#E8F5E9"/>
+  <path
+      android:pathData="M400.573,190.501l-10.607,10.607l-10.607,-10.607l10.607,-10.607z"
+      android:fillColor="#E8F5E9"/>
 </vector>
diff --git a/core/res/res/drawable-nodpi/stat_sys_adb.xml b/core/res/res/drawable-nodpi/stat_sys_adb.xml
index 6ce4b9d..973010e 100644
--- a/core/res/res/drawable-nodpi/stat_sys_adb.xml
+++ b/core/res/res/drawable-nodpi/stat_sys_adb.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
 Copyright (C) 2024 The Android Open Source Project
 
@@ -13,7 +14,6 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:width="24dp"
     android:height="24dp"
@@ -21,104 +21,35 @@
     android:viewportHeight="24">
   <group>
     <clip-path
-        android:pathData="
-            M12.6495 17.375
-            C12.3608 17.875 11.6392 17.875 11.3505 17.375
-            L3.98927 4.625
-            C3.70059 4.125 4.06143 3.5 4.63878 3.5
-            L19.3612 3.5
-            C19.9386 3.5 20.2994 4.125 20.0107 4.625
-            L12.6495 17.375
-            Z
-        "/>
+        android:pathData="M0,0h24v24h-24z"/>
     <path
-        android:pathData="M5,12 h14v9.8h-14z"
-        android:fillColor="#ffffff"/>
+        android:pathData="M12,8V12H8L12,8Z"
+        android:fillColor="#D9D9D9"/>
     <path
-        android:pathData="
-            M15.97 10.48
-            C15.97 10.46 15.97 10.45 15.96 10.43
-            C15.95 10.33 15.93 10.23 15.90 10.13
-            C15.86 9.96 15.81 9.79 15.75 9.63
-            C15.69 9.50 15.63 9.36 15.57 9.23
-            C15.48 9.07 15.38 8.91 15.27 8.76
-            C15.14 8.57 14.99 8.40 14.83 8.24
-            C14.76 8.17 14.69 8.11 14.62 8.04
-            C14.47 7.91 14.30 7.78 14.12 7.67
-            C14.12 7.67 14.13 7.67 14.13 7.67
-            C14.21 7.53 14.29 7.39 14.37 7.25
-            C14.45 7.11 14.53 6.98 14.61 6.84
-            C14.66 6.74 14.72 6.64 14.78 6.55
-            C14.79 6.52 14.80 6.50 14.81 6.48
-            C14.83 6.41 14.83 6.33 14.81 6.27
-            C14.81 6.25 14.80 6.24 14.80 6.22
-            C14.79 6.20 14.78 6.19 14.77 6.17
-            C14.74 6.12 14.70 6.08 14.65 6.05
-            C14.60 6.02 14.54 6 14.49 6
-            C14.47 5.99 14.44 5.99 14.42 6
-            C14.40 6 14.38 6 14.36 6.01
-            C14.30 6.02 14.23 6.06 14.19 6.11
-            C14.17 6.13 14.15 6.15 14.14 6.18
-            C14.08 6.28 14.03 6.37 13.97 6.47
-            L13.73 6.88
-            C13.65 7.02 13.57 7.16 13.49 7.30
-            C13.48 7.31 13.47 7.33 13.46 7.34
-            C13.45 7.34 13.44 7.33 13.43 7.33
-            C12.98 7.16 12.50 7.07 12 7.07
-            C11.98 7.07 11.97 7.07 11.95 7.07
-            C11.51 7.07 11.07 7.15 10.67 7.29
-            C10.63 7.31 10.58 7.32 10.53 7.34
-            C10.53 7.33 10.52 7.31 10.51 7.30
-            C10.43 7.16 10.35 7.02 10.27 6.88
-            C10.19 6.74 10.11 6.61 10.03 6.47
-            C9.97 6.37 9.92 6.28 9.86 6.18
-            C9.85 6.15 9.83 6.13 9.81 6.11
-            C9.77 6.06 9.70 6.03 9.64 6.01
-            C9.62 6 9.60 6 9.58 6
-            C9.56 5.99 9.53 5.99 9.51 6
-            C9.46 6 9.40 6.02 9.35 6.05
-            C9.30 6.08 9.26 6.12 9.23 6.17
-            C9.22 6.19 9.21 6.20 9.20 6.22
-            C9.20 6.24 9.19 6.25 9.19 6.27
-            C9.17 6.34 9.17 6.41 9.19 6.48
-            C9.20 6.50 9.21 6.52 9.22 6.55
-            C9.28 6.65 9.34 6.74 9.39 6.84
-            C9.47 6.98 9.55 7.11 9.63 7.25
-            C9.71 7.39 9.79 7.53 9.87 7.67
-            C9.87 7.67 9.87 7.67 9.88 7.67
-            C9.71 7.77 9.56 7.88 9.41 8.01
-            C9.32 8.08 9.24 8.16 9.16 8.24
-            C9 8.40 8.85 8.57 8.72 8.76
-            C8.61 8.91 8.51 9.07 8.43 9.23
-            C8.36 9.36 8.30 9.50 8.24 9.63
-            C8.18 9.79 8.13 9.96 8.09 10.13
-            C8.06 10.23 8.04 10.33 8.03 10.43
-            C8.02 10.45 8.02 10.46 8.02 10.48
-            C8.01 10.54 8 10.60 8 10.65
-            L16 10.65
-            C15.99 10.60 15.98 10.54 15.97 10.48
-            L15.97 10.48
-            Z
-        "
-        android:fillColor="#ffffff"/>
+        android:pathData="M12,4V8H8L12,4Z"
+        android:fillColor="#D9D9D9"/>
+    <path
+        android:pathData="M8,8V12H4L8,8Z"
+        android:fillColor="#D9D9D9"/>
+    <path
+        android:pathData="M12,16L12,12L16,12L12,16Z"
+        android:fillColor="#D9D9D9"/>
+    <path
+        android:pathData="M12,20L12,16L16,16L12,20Z"
+        android:fillColor="#D9D9D9"/>
+    <path
+        android:pathData="M16,16L16,12L20,12L16,16Z"
+        android:fillColor="#D9D9D9"/>
+    <path
+        android:pathData="M12,8L16,8L16,12L12,8Z"
+        android:fillColor="#D9D9D9"/>
+    <path
+        android:pathData="M12,16L8,16L8,12L12,16Z"
+        android:fillColor="#D9D9D9"/>
+    <path
+        android:pathData="M13.096,2.0354L21.9646,10.904A1.55,1.55 90,0 1,21.9646 13.096L13.096,21.9646A1.55,1.55 90,0 1,10.904 21.9646L2.0354,13.096A1.55,1.55 0,0 1,2.0354 10.904L10.904,2.0354A1.55,1.55 0,0 1,13.096 2.0354z"
+        android:strokeWidth="1.5"
+        android:fillColor="#00000000"
+        android:strokeColor="#FF00FF"/>
   </group>
-  <path
-      android:pathData="
-          M12,20.923
-          C10.764,20.923 9.946,20.065 9.131,18.653
-          C8.316,17.241 4.291,10.269 3.476,8.857
-          C2.66,7.445 2.326,6.309 2.944,5.238
-          C3.563,4.167 4.714,3.888 6.344,3.888
-          C7.975,3.888 16.025,3.888 17.656,3.888
-          C19.286,3.888 20.437,4.167 21.056,5.238
-          C21.674,6.309 21.34,7.445 20.524,8.857
-          C19.709,10.269 15.684,17.241 14.869,18.653
-          C14.054,20.065 13.236,20.923 12,20.923
-          H12
-          Z
-      "
-      android:strokeWidth="2"
-      android:fillColor="#00000000"
-      android:strokeColor="#ffffff"/>
 </vector>
-
diff --git a/core/res/res/drawable/ic_notification_2025_collapse.xml b/core/res/res/drawable/ic_notification_2025_collapse.xml
new file mode 100644
index 0000000..1b40c55
--- /dev/null
+++ b/core/res/res/drawable/ic_notification_2025_collapse.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright (C) 2024 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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M480,432L296,616L240,560L480,320L720,560L664,616L480,432Z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_notification_2025_expand.xml b/core/res/res/drawable/ic_notification_2025_expand.xml
new file mode 100644
index 0000000..ea5e0f0
--- /dev/null
+++ b/core/res/res/drawable/ic_notification_2025_expand.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright (C) 2024 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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M480,616L240,376L296,320L480,504L664,320L720,376L480,616Z"/>
+</vector>
diff --git a/core/res/res/drawable/notification_2025_expand_button_pill_bg.xml b/core/res/res/drawable/notification_2025_expand_button_pill_bg.xml
new file mode 100644
index 0000000..74f697a
--- /dev/null
+++ b/core/res/res/drawable/notification_2025_expand_button_pill_bg.xml
@@ -0,0 +1,29 @@
+<!--
+  ~ Copyright (C) 2024 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.
+  -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/expand_button_pill_colorized_layer">
+        <shape xmlns:android="http://schemas.android.com/apk/res/android">
+            <corners android:radius="@dimen/notification_2025_expand_button_pill_height" />
+            <solid android:color="@android:color/white" />
+        </shape>
+    </item>
+    <item>
+        <shape xmlns:android="http://schemas.android.com/apk/res/android">
+            <corners android:radius="@dimen/notification_2025_expand_button_pill_height" />
+            <solid android:color="@color/notification_expand_button_state_tint" />
+        </shape>
+    </item>
+</layer-list>
diff --git a/core/res/res/layout/notification_2025_expand_button.xml b/core/res/res/layout/notification_2025_expand_button.xml
new file mode 100644
index 0000000..c8263c2
--- /dev/null
+++ b/core/res/res/layout/notification_2025_expand_button.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2024 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
+  -->
+
+<!-- extends FrameLayout -->
+<com.android.internal.widget.NotificationExpandButton
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/expand_button"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="top|end"
+    android:contentDescription="@string/expand_button_content_description_collapsed"
+    >
+
+    <LinearLayout
+        android:id="@+id/expand_button_pill"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:minHeight="@dimen/notification_2025_expand_button_pill_height"
+        android:minWidth="@dimen/notification_2025_expand_button_pill_width"
+        android:paddingVertical="@dimen/notification_2025_expand_button_vertical_icon_padding"
+        android:paddingHorizontal="@dimen/notification_2025_expand_button_horizontal_icon_padding"
+        android:orientation="horizontal"
+        android:background="@drawable/notification_2025_expand_button_pill_bg"
+        android:gravity="center"
+        android:layout_gravity="center_vertical"
+        android:duplicateParentState="true"
+        >
+
+        <TextView
+            android:id="@+id/expand_button_number"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Info"
+            android:gravity="center_vertical"
+            android:visibility="gone"
+            />
+
+        <ImageView
+            android:id="@+id/expand_button_icon"
+            android:layout_width="@dimen/notification_2025_expand_button_icon_size"
+            android:layout_height="@dimen/notification_2025_expand_button_icon_size"
+            android:scaleType="fitCenter"
+            android:importantForAccessibility="no"
+            />
+
+    </LinearLayout>
+
+</com.android.internal.widget.NotificationExpandButton>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_base.xml b/core/res/res/layout/notification_2025_template_collapsed_base.xml
index e91e111..c827dcb 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_base.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_base.xml
@@ -164,10 +164,11 @@
             android:minWidth="@dimen/notification_content_margin_end"
             >
 
-            <include layout="@layout/notification_expand_button"
+            <include layout="@layout/notification_2025_expand_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical|end"
+                android:layout_gravity="top|end"
+                android:layout_margin="@dimen/notification_2025_margin"
                 />
 
         </FrameLayout>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_call.xml b/core/res/res/layout/notification_2025_template_collapsed_call.xml
index c4bca11..ce38c164 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_call.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_call.xml
@@ -66,10 +66,11 @@
             >
 
             <include
-                layout="@layout/notification_expand_button"
+                layout="@layout/notification_2025_expand_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical"
+                android:layout_gravity="top|end"
+                android:layout_margin="@dimen/notification_2025_margin"
                 />
 
         </FrameLayout>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_media.xml b/core/res/res/layout/notification_2025_template_collapsed_media.xml
index 2d36733..0021b83 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_media.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_media.xml
@@ -185,10 +185,11 @@
             android:minWidth="@dimen/notification_content_margin_end"
             >
 
-            <include layout="@layout/notification_expand_button"
+            <include layout="@layout/notification_2025_expand_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical|end"
+                android:layout_gravity="top|end"
+                android:layout_margin="@dimen/notification_2025_margin"
                 />
 
         </FrameLayout>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_messaging.xml b/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
index fbecb8c..f3e4ce1 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
@@ -189,10 +189,11 @@
                     android:minWidth="@dimen/notification_content_margin_end"
                     >
 
-                    <include layout="@layout/notification_expand_button"
+                    <include layout="@layout/notification_2025_expand_button"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
-                        android:layout_gravity="center_vertical|end"
+                        android:layout_gravity="top|end"
+                        android:layout_margin="@dimen/notification_2025_margin"
                         />
 
                 </FrameLayout>
diff --git a/core/res/res/layout/notification_2025_template_conversation.xml b/core/res/res/layout/notification_2025_template_conversation.xml
index f31f65e..6be5a1c 100644
--- a/core/res/res/layout/notification_2025_template_conversation.xml
+++ b/core/res/res/layout/notification_2025_template_conversation.xml
@@ -148,10 +148,11 @@
                     android:clipToPadding="false"
                     android:clipChildren="false"
                     />
-                <include layout="@layout/notification_expand_button"
+                <include layout="@layout/notification_2025_expand_button"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:layout_gravity="center"
+                    android:layout_gravity="top|end"
+                    android:layout_margin="@dimen/notification_2025_margin"
                     />
             </LinearLayout>
         </LinearLayout>
diff --git a/core/res/res/layout/notification_2025_template_expanded_base.xml b/core/res/res/layout/notification_2025_template_expanded_base.xml
index e480fe5..d364c65 100644
--- a/core/res/res/layout/notification_2025_template_expanded_base.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_base.xml
@@ -40,13 +40,14 @@
 
             <include layout="@layout/notification_2025_template_header" />
 
+            <!-- Note: the top margin is being set in code based on the estimated space needed for
+            the header text. -->
             <LinearLayout
                 android:id="@+id/notification_main_column"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginStart="@dimen/notification_2025_content_margin_start"
                 android:layout_marginEnd="@dimen/notification_content_margin_end"
-                android:layout_marginTop="@dimen/notification_content_margin_top"
                 android:orientation="vertical"
                 >
 
diff --git a/core/res/res/layout/notification_2025_template_expanded_big_picture.xml b/core/res/res/layout/notification_2025_template_expanded_big_picture.xml
index 18bafe0..12e1172 100644
--- a/core/res/res/layout/notification_2025_template_expanded_big_picture.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_big_picture.xml
@@ -32,11 +32,12 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_gravity="top"
-        android:layout_marginTop="@dimen/notification_content_margin_top"
         android:clipToPadding="false"
         android:orientation="vertical"
         >
 
+        <!-- Note: the top margin is being set in code based on the estimated space needed for
+        the header text. -->
         <LinearLayout
             android:id="@+id/notification_main_column"
             android:layout_width="match_parent"
diff --git a/core/res/res/layout/notification_2025_template_expanded_big_text.xml b/core/res/res/layout/notification_2025_template_expanded_big_text.xml
index 9ff141b..c9dd868 100644
--- a/core/res/res/layout/notification_2025_template_expanded_big_text.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_big_text.xml
@@ -30,12 +30,13 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="top"
-        android:layout_marginTop="@dimen/notification_content_margin_top"
         android:layout_marginBottom="@dimen/notification_content_margin"
         android:clipToPadding="false"
         android:orientation="vertical"
         >
 
+        <!-- Note: the top margin is being set in code based on the estimated space needed for
+        the header text. -->
         <com.android.internal.widget.RemeasuringLinearLayout
             android:id="@+id/notification_main_column"
             android:layout_width="match_parent"
diff --git a/core/res/res/layout/notification_2025_template_expanded_call.xml b/core/res/res/layout/notification_2025_template_expanded_call.xml
index 2af0ec2..0be6125 100644
--- a/core/res/res/layout/notification_2025_template_expanded_call.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_call.xml
@@ -48,8 +48,8 @@
                 android:id="@+id/notification_main_column"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_weight="1"
                 android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+                android:layout_weight="1"
                 android:orientation="vertical"
                 android:minHeight="68dp"
                 >
diff --git a/core/res/res/layout/notification_2025_template_expanded_inbox.xml b/core/res/res/layout/notification_2025_template_expanded_inbox.xml
index 9fb44ccc..8434b36 100644
--- a/core/res/res/layout/notification_2025_template_expanded_inbox.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_inbox.xml
@@ -28,10 +28,11 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_gravity="top"
-            android:layout_marginTop="@dimen/notification_content_margin_top"
             android:clipToPadding="false"
             android:orientation="vertical">
 
+        <!-- Note: the top margin is being set in code based on the estimated space needed for
+        the header text. -->
         <LinearLayout
             android:id="@+id/notification_main_column"
             android:layout_width="match_parent"
diff --git a/core/res/res/layout/notification_2025_template_expanded_media.xml b/core/res/res/layout/notification_2025_template_expanded_media.xml
index 578a0b2..e90ab79 100644
--- a/core/res/res/layout/notification_2025_template_expanded_media.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_media.xml
@@ -34,11 +34,12 @@
         android:id="@+id/notification_media_content"
         >
 
+        <!-- Note: the top margin is being set in code based on the estimated space needed for
+        the header text. -->
         <LinearLayout
             android:id="@+id/notification_main_column"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/notification_content_margin_top"
             android:layout_marginStart="@dimen/notification_2025_content_margin_start"
             android:layout_marginEnd="@dimen/notification_content_margin_end"
             android:orientation="vertical"
diff --git a/core/res/res/layout/notification_2025_template_expanded_messaging.xml b/core/res/res/layout/notification_2025_template_expanded_messaging.xml
index e3c2014..7f5a36b 100644
--- a/core/res/res/layout/notification_2025_template_expanded_messaging.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_messaging.xml
@@ -33,10 +33,11 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="top"
-            android:layout_marginTop="@dimen/notification_2025_header_height"
             android:clipChildren="false"
             android:orientation="vertical">
 
+        <!-- Note: the top margin is being set in code based on the estimated space needed for
+        the header text. -->
         <com.android.internal.widget.RemeasuringLinearLayout
             android:id="@+id/notification_main_column"
             android:layout_width="match_parent"
diff --git a/core/res/res/layout/notification_2025_template_expanded_progress.xml b/core/res/res/layout/notification_2025_template_expanded_progress.xml
index afa4bc6..5d4fc4c 100644
--- a/core/res/res/layout/notification_2025_template_expanded_progress.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_progress.xml
@@ -41,13 +41,14 @@
 
             <include layout="@layout/notification_2025_template_header" />
 
+            <!-- Note: the top margin is being set in code based on the estimated space needed for
+            the header text. -->
             <LinearLayout
                 android:id="@+id/notification_main_column"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginStart="@dimen/notification_2025_content_margin_start"
                 android:layout_marginEnd="@dimen/notification_content_margin_end"
-                android:layout_marginTop="@dimen/notification_content_margin_top"
                 android:orientation="vertical"
                 >
 
diff --git a/core/res/res/layout/notification_2025_template_header.xml b/core/res/res/layout/notification_2025_template_header.xml
index 2d30d8a..3f34eb3 100644
--- a/core/res/res/layout/notification_2025_template_header.xml
+++ b/core/res/res/layout/notification_2025_template_header.xml
@@ -57,11 +57,11 @@
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/notification_top_line"
         android:layout_width="wrap_content"
-        android:layout_height="match_parent"
+        android:layout_height="wrap_content"
         android:layout_alignParentStart="true"
-        android:layout_centerVertical="true"
         android:layout_toStartOf="@id/expand_button"
         android:layout_alignWithParentIfMissing="true"
+        android:layout_marginVertical="@dimen/notification_2025_margin"
         android:clipChildren="false"
         android:gravity="center_vertical"
         android:paddingStart="@dimen/notification_2025_content_margin_start"
@@ -81,10 +81,11 @@
         android:focusable="false"
         />
 
-    <include layout="@layout/notification_expand_button"
+    <include layout="@layout/notification_2025_expand_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_centerVertical="true"
+        android:layout_gravity="top|end"
+        android:layout_margin="@dimen/notification_2025_margin"
         android:layout_alignParentEnd="true" />
 
     <include layout="@layout/notification_close_button"
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index ca542ba..66bc41f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1160,20 +1160,20 @@
     <string name="duration_years_shortest_future" msgid="5537464088352970388">"in <xliff:g id="COUNT">%d</xliff:g> J"</string>
     <string name="duration_minutes_shortest_past" msgid="1740022450020492407">"vor <xliff:g id="COUNT">%d</xliff:g> Min."</string>
     <string name="duration_hours_shortest_past" msgid="2098397414186628489">"vor <xliff:g id="COUNT">%d</xliff:g> Std."</string>
-    <string name="duration_days_shortest_past" msgid="1832006037955897625">"vor <xliff:g id="COUNT">%d</xliff:g> Tg."</string>
-    <string name="duration_years_shortest_past" msgid="6168256514200469291">"vor <xliff:g id="COUNT">%d</xliff:g> J."</string>
+    <string name="duration_days_shortest_past" msgid="1832006037955897625">"vor <xliff:g id="COUNT">%d</xliff:g> T"</string>
+    <string name="duration_years_shortest_past" msgid="6168256514200469291">"vor <xliff:g id="COUNT">%d</xliff:g> J"</string>
     <string name="duration_minutes_medium" msgid="5891933490342643944">"<xliff:g id="COUNT">%d</xliff:g> Min."</string>
     <string name="duration_hours_medium" msgid="1465359726485910115">"<xliff:g id="COUNT">%d</xliff:g> Std."</string>
-    <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> Tg."</string>
-    <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> J."</string>
+    <string name="duration_days_medium" msgid="5994225628248661388">"<xliff:g id="COUNT">%d</xliff:g> T"</string>
+    <string name="duration_years_medium" msgid="734023884353592526">"<xliff:g id="COUNT">%d</xliff:g> J"</string>
     <string name="duration_minutes_medium_future" msgid="2750894988731934402">"in <xliff:g id="COUNT">%d</xliff:g> Min."</string>
     <string name="duration_hours_medium_future" msgid="6050833881463849764">"in <xliff:g id="COUNT">%d</xliff:g> Std."</string>
-    <string name="duration_days_medium_future" msgid="1700821545602729963">"in <xliff:g id="COUNT">%d</xliff:g> Tg."</string>
-    <string name="duration_years_medium_future" msgid="3281018940397120166">"in <xliff:g id="COUNT">%d</xliff:g> J."</string>
+    <string name="duration_days_medium_future" msgid="1700821545602729963">"in <xliff:g id="COUNT">%d</xliff:g> T"</string>
+    <string name="duration_years_medium_future" msgid="3281018940397120166">"in <xliff:g id="COUNT">%d</xliff:g> J"</string>
     <string name="duration_minutes_medium_past" msgid="7400424340181947714">"vor <xliff:g id="COUNT">%d</xliff:g> Min."</string>
     <string name="duration_hours_medium_past" msgid="6709441336035202617">"vor <xliff:g id="COUNT">%d</xliff:g> Std."</string>
-    <string name="duration_days_medium_past" msgid="5748156261134344532">"vor <xliff:g id="COUNT">%d</xliff:g> Tg."</string>
-    <string name="duration_years_medium_past" msgid="893797065424596243">"vor <xliff:g id="COUNT">%d</xliff:g> J."</string>
+    <string name="duration_days_medium_past" msgid="5748156261134344532">"vor <xliff:g id="COUNT">%d</xliff:g> T"</string>
+    <string name="duration_years_medium_past" msgid="893797065424596243">"vor <xliff:g id="COUNT">%d</xliff:g> J"</string>
     <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{Vor # Minute}other{Vor # Minuten}}"</string>
     <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{Vor # Stunde}other{Vor # Stunden}}"</string>
     <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{Vor # Tag}other{Vor # Tagen}}"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 0ddbc41..0c7d868 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1404,7 +1404,7 @@
     <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Last ned <xliff:g id="APP_NAME">%1$s</xliff:g>-appen for å aktivere det nye SIM-kortet ditt"</string>
     <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Last ned appen"</string>
     <string name="carrier_app_notification_title" msgid="5815477368072060250">"Et nytt SIM-kort er satt inn"</string>
-    <string name="carrier_app_notification_text" msgid="6567057546341958637">"Trykk for å konfigurere"</string>
+    <string name="carrier_app_notification_text" msgid="6567057546341958637">"Konfigurer"</string>
     <string name="time_picker_dialog_title" msgid="9053376764985220821">"Angi tidspunkt"</string>
     <string name="date_picker_dialog_title" msgid="5030520449243071926">"Angi dato"</string>
     <string name="date_time_set" msgid="4603445265164486816">"Lagre"</string>
@@ -1469,7 +1469,7 @@
     <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Analyserer medielagring"</string>
     <string name="ext_media_new_notification_title" msgid="3517407571407687677">"Ny <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> fungerer ikke"</string>
-    <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Trykk for å konfigurere"</string>
+    <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Konfigurer"</string>
     <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Velg for å konfigurere"</string>
     <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Du må muligens reformatere enheten. Trykk for å løse ut."</string>
     <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"For lagring av bilder, videoer, musikk med mer"</string>
@@ -1481,7 +1481,7 @@
     <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"Du må muligens reformatere enheten. Trykk for å løse ut."</string>
     <string name="ext_media_unsupported_notification_title" msgid="3487534182861251401">"<xliff:g id="NAME">%s</xliff:g> er oppdaget"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> fungerer ikke"</string>
-    <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"Trykk for å konfigurere."</string>
+    <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"Konfigurer."</string>
     <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"Velg for å konfigurere <xliff:g id="NAME">%s</xliff:g> i et format som støttes."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Du må muligens reformatere enheten"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> ble uventet fjernet"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index c9a922e..3414644 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1019,7 +1019,7 @@
     <string name="lockscreen_permanent_disabled_sim_instructions" msgid="6902979937802238429">"तपाईंको SIM कार्ड सदाका लागि डिएक्टिभेट गरिएको छ।\n आफ्नो वायरलेस सेवा प्रदायकलाई सम्पर्क गरी अर्को SIM कार्ड प्राप्त गर्नुहोस्।"</string>
     <string name="lockscreen_transport_prev_description" msgid="2879469521751181478">"अघिल्लो ट्रयाक"</string>
     <string name="lockscreen_transport_next_description" msgid="2931509904881099919">"अर्को ट्रयाक"</string>
-    <string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"रोक्नुहोस्"</string>
+    <string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"पज गर्नुहोस्"</string>
     <string name="lockscreen_transport_play_description" msgid="106868788691652733">"चलाउनुहोस्"</string>
     <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"रोक्नुहोस्"</string>
     <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"दोहोर्याउनुहोस्"</string>
diff --git a/core/res/res/values/config_display.xml b/core/res/res/values/config_display.xml
index c458d0e9..b6500b7 100644
--- a/core/res/res/values/config_display.xml
+++ b/core/res/res/values/config_display.xml
@@ -31,5 +31,8 @@
     <bool name="config_evenDimmerEnabled">false</bool>
     <!-- Jar file path to look for PluginProvider -->
     <string name="config_pluginsProviderJarPath"/>
-
+    <!-- Indicate available EM_VALUE options -->
+    <integer-array name="config_availableEMValueOptions">
+        <item>0</item> <!-- DEFAULT -->
+    </integer-array>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index fb21c75..a4735fe 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -310,9 +310,15 @@
     <!-- Size of the stroke with for the emphasized notification button style -->
     <dimen name="emphasized_button_stroke_width">1dp</dimen>
 
-    <!-- height of the content margin to accomodate for the header -->
+    <!-- height of the content margin to accommodate for the header -->
     <dimen name="notification_content_margin_top">50dp</dimen>
 
+    <!-- The spacing between the content and the header text above it, scaling with text size.
+         This value is chosen so that, taking into account the text spacing for both the text in the
+         top line and the text in the content, the distance between them is 4dp with the default
+         screen configuration (and will grow accordingly for larger font sizes) -->
+    <dimen name="notification_2025_content_margin_top">10sp</dimen>
+
     <!-- height of the content margin that is applied at the end of the notification content -->
     <dimen name="notification_content_margin">20dp</dimen>
 
@@ -384,9 +390,24 @@
     <!-- the height of the expand button pill -->
     <dimen name="notification_expand_button_pill_height">24dp</dimen>
 
+    <!-- the height of the expand button pill (2025 redesign version) -->
+    <dimen name="notification_2025_expand_button_pill_height">20dp</dimen>
+
+    <!-- the width of the expand button pill (2025 redesign version) -->
+    <dimen name="notification_2025_expand_button_pill_width">28dp</dimen>
+
+    <!-- the size of the expand arrow (2025 redesign version) -->
+    <dimen name="notification_2025_expand_button_icon_size">16sp</dimen>
+
     <!-- the padding of the expand icon in the notification header -->
     <dimen name="notification_expand_button_icon_padding">2dp</dimen>
 
+    <!-- the padding of the expand icon in the notification header -->
+    <dimen name="notification_2025_expand_button_vertical_icon_padding">2dp</dimen>
+
+    <!-- the padding of the expand icon in the notification header -->
+    <dimen name="notification_2025_expand_button_horizontal_icon_padding">6dp</dimen>
+
     <!-- the size of the notification close button -->
     <dimen name="notification_close_button_size">16dp</dimen>
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index cfc3ddc..33d3858 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -246,6 +246,8 @@
     <string name="NetworkPreferenceSwitchSummary">Try changing preferred network. Tap to change.</string>
     <!-- Displayed to tell the user that emergency calls might not be available. -->
     <string name="EmergencyCallWarningTitle">Emergency calling unavailable</string>
+    <!-- Displayed to tell the user that the notification can be permanently turned off -->
+    <string name="emergency_calling_do_not_show_again">Do Not Show Again</string>
     <!-- Displayed to tell the user that emergency calls might not be available; this is shown to
          the user when only WiFi calling is available and the carrier does not support emergency
          calls over WiFi calling. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8195d38..4789624 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -640,6 +640,7 @@
   <java-symbol type="string" name="auto_data_switch_title" />
   <java-symbol type="string" name="auto_data_switch_content" />
   <java-symbol type="string" name="RestrictedStateContentMsimTemplate" />
+  <java-symbol type="string" name="emergency_calling_do_not_show_again" />
   <java-symbol type="string" name="notification_channel_network_alert" />
   <java-symbol type="string" name="notification_channel_call_forward" />
   <java-symbol type="string" name="notification_channel_emergency_callback" />
@@ -1308,6 +1309,7 @@
   <java-symbol type="array" name="config_securityStatePackages" />
   <java-symbol type="array" name="stoppable_fgs_system_apps" />
   <java-symbol type="array" name="vendor_stoppable_fgs_system_apps" />
+  <java-symbol type="array" name="config_availableEMValueOptions" />
 
   <java-symbol type="drawable" name="default_wallpaper" />
   <java-symbol type="drawable" name="default_lock_wallpaper" />
@@ -3229,6 +3231,8 @@
   <java-symbol type="id" name="header_text_divider" />
   <java-symbol type="id" name="header_text_secondary_divider" />
   <java-symbol type="drawable" name="ic_expand_notification" />
+  <java-symbol type="drawable" name="ic_notification_2025_collapse" />
+  <java-symbol type="drawable" name="ic_notification_2025_expand" />
   <java-symbol type="drawable" name="ic_collapse_notification" />
   <java-symbol type="drawable" name="notification_close_button_icon" />
   <java-symbol type="drawable" name="ic_expand_bundle" />
@@ -3241,6 +3245,8 @@
   <java-symbol type="dimen" name="notification_heading_margin_end" />
   <java-symbol type="dimen" name="notification_content_margin_top" />
   <java-symbol type="dimen" name="notification_content_margin" />
+  <java-symbol type="dimen" name="notification_2025_margin" />
+  <java-symbol type="dimen" name="notification_2025_content_margin_top" />
   <java-symbol type="dimen" name="notification_progress_margin_horizontal" />
   <java-symbol type="dimen" name="notification_header_background_height" />
   <java-symbol type="dimen" name="notification_header_touchable_height" />
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 3ef3dfd..d7c4212 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -73,6 +73,7 @@
         "frameworks-core-util-lib",
         "mockwebserver",
         "guava",
+        "guava-android-testlib",
         "android.app.usage.flags-aconfig-java",
         "android.view.accessibility.flags-aconfig-java",
         "androidx.core_core",
diff --git a/core/tests/coretests/src/android/app/BackgroundStartPrivilegesTest.java b/core/tests/coretests/src/android/app/BackgroundStartPrivilegesTest.java
index 931d646..f1925bb 100644
--- a/core/tests/coretests/src/android/app/BackgroundStartPrivilegesTest.java
+++ b/core/tests/coretests/src/android/app/BackgroundStartPrivilegesTest.java
@@ -29,6 +29,8 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.google.common.testing.EqualsTester;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -122,12 +124,16 @@
 
     @Test
     public void backgroundStartPrivilege_equals_works() {
-        assertThat(NONE).isEqualTo(NONE);
-        assertThat(ALLOW_BAL).isEqualTo(ALLOW_BAL);
-        assertThat(ALLOW_FGS).isEqualTo(ALLOW_FGS);
-        assertThat(BSP_ALLOW_A).isEqualTo(BSP_ALLOW_A);
-        assertThat(NONE).isNotEqualTo(ALLOW_BAL);
-        assertThat(ALLOW_FGS).isNotEqualTo(ALLOW_BAL);
-        assertThat(BSP_ALLOW_A).isNotEqualTo(BSP_ALLOW_B);
+        Binder token = new Binder();
+        Binder anotherToken = new Binder();
+        new EqualsTester()
+                .addEqualityGroup(NONE)
+                .addEqualityGroup(ALLOW_BAL)
+                .addEqualityGroup(ALLOW_FGS)
+                .addEqualityGroup(BackgroundStartPrivileges.allowBackgroundActivityStarts(token),
+                        BackgroundStartPrivileges.allowBackgroundActivityStarts(token))
+                .addEqualityGroup(
+                        BackgroundStartPrivileges.allowBackgroundActivityStarts(anotherToken))
+                .testEquals();
     }
 }
diff --git a/core/tests/coretests/src/android/app/NotificationManagerTest.java b/core/tests/coretests/src/android/app/NotificationManagerTest.java
index a47fc94..6538ce8 100644
--- a/core/tests/coretests/src/android/app/NotificationManagerTest.java
+++ b/core/tests/coretests/src/android/app/NotificationManagerTest.java
@@ -18,9 +18,11 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.atMost;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -104,6 +106,22 @@
 
     @Test
     @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+    public void notifyAsPackage_rapidUpdate_isThrottled() throws Exception {
+        Notification n = exampleNotification();
+
+        for (int i = 0; i < 100; i++) {
+            mNotificationManager.notifyAsPackage("some.package.name", "tag", 1, n);
+            mClock.advanceByMillis(5);
+        }
+
+        verify(mNotificationManager.mBackendService, atLeast(20)).enqueueNotificationWithTag(
+                eq("some.package.name"), any(), any(), anyInt(), any(), anyInt());
+        verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(
+                eq("some.package.name"), any(), any(), anyInt(), any(), anyInt());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
     public void cancel_unnecessaryAndRapid_isThrottled() throws Exception {
 
         for (int i = 0; i < 100; i++) {
@@ -165,6 +183,66 @@
                 any(), any(), anyInt(), anyInt());
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+    public void enqueue_afterCancel_isNotUpdateAndIsNotThrottled() throws Exception {
+        // First, hit the enqueue threshold.
+        Notification n = exampleNotification();
+        for (int i = 0; i < 100; i++) {
+            mNotificationManager.notify(1, n);
+            mClock.advanceByMillis(1);
+        }
+        verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(any(),
+                any(), any(), anyInt(), any(), anyInt());
+        reset(mNotificationManager.mBackendService);
+
+        // Now cancel that notification and then post it again. That should work.
+        mNotificationManager.cancel(1);
+        mNotificationManager.notify(1, n);
+        verify(mNotificationManager.mBackendService).enqueueNotificationWithTag(any(), any(), any(),
+                anyInt(), any(), anyInt());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+    public void enqueue_afterCancelAsPackage_isNotUpdateAndIsNotThrottled() throws Exception {
+        // First, hit the enqueue threshold.
+        Notification n = exampleNotification();
+        for (int i = 0; i < 100; i++) {
+            mNotificationManager.notify(1, n);
+            mClock.advanceByMillis(1);
+        }
+        verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(any(),
+                any(), any(), anyInt(), any(), anyInt());
+        reset(mNotificationManager.mBackendService);
+
+        // Now cancel that notification and then post it again. That should work.
+        mNotificationManager.cancelAsPackage(mContext.getPackageName(), /* tag= */ null, 1);
+        mNotificationManager.notify(1, n);
+        verify(mNotificationManager.mBackendService).enqueueNotificationWithTag(any(), any(), any(),
+                anyInt(), any(), anyInt());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+    public void enqueue_afterCancelAll_isNotUpdateAndIsNotThrottled() throws Exception {
+        // First, hit the enqueue threshold.
+        Notification n = exampleNotification();
+        for (int i = 0; i < 100; i++) {
+            mNotificationManager.notify(1, n);
+            mClock.advanceByMillis(1);
+        }
+        verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(any(),
+                any(), any(), anyInt(), any(), anyInt());
+        reset(mNotificationManager.mBackendService);
+
+        // Now cancel all notifications and then post it again. That should work.
+        mNotificationManager.cancelAll();
+        mNotificationManager.notify(1, n);
+        verify(mNotificationManager.mBackendService).enqueueNotificationWithTag(any(), any(), any(),
+                anyInt(), any(), anyInt());
+    }
+
     private Notification exampleNotification() {
         return new Notification.Builder(mContext, "channel")
                 .setSmallIcon(android.R.drawable.star_big_on)
diff --git a/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java b/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java
index a270848..8fa5103 100644
--- a/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java
+++ b/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java
@@ -302,48 +302,48 @@
 
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_DISPLAY_LISTENER_PERFORMANCE_IMPROVEMENTS)
-    public void testMapFlagsToInternalEventFlag() {
+    public void testMapFiltersToInternalEventFlag() {
         // Test public flags mapping
         assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_ADDED,
                 mDisplayManagerGlobal
-                        .mapFlagsToInternalEventFlag(DisplayManager.EVENT_FLAG_DISPLAY_ADDED, 0));
+                        .mapFiltersToInternalEventFlag(DisplayManager.EVENT_TYPE_DISPLAY_ADDED, 0));
         assertEquals(DISPLAY_CHANGE_EVENTS, mDisplayManagerGlobal
-                        .mapFlagsToInternalEventFlag(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED, 0));
+                .mapFiltersToInternalEventFlag(DisplayManager.EVENT_TYPE_DISPLAY_CHANGED, 0));
         assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_REMOVED,
-                mDisplayManagerGlobal
-                        .mapFlagsToInternalEventFlag(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED, 0));
+                mDisplayManagerGlobal.mapFiltersToInternalEventFlag(
+                        DisplayManager.EVENT_TYPE_DISPLAY_REMOVED, 0));
         assertEquals(INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE,
                 mDisplayManagerGlobal
-                        .mapFlagsToInternalEventFlag(
-                                DisplayManager.EVENT_FLAG_DISPLAY_REFRESH_RATE,
+                        .mapFiltersToInternalEventFlag(
+                                DisplayManager.EVENT_TYPE_DISPLAY_REFRESH_RATE,
                                 0));
         assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_STATE,
                 mDisplayManagerGlobal
-                        .mapFlagsToInternalEventFlag(
-                                DisplayManager.EVENT_FLAG_DISPLAY_STATE,
+                        .mapFiltersToInternalEventFlag(
+                                DisplayManager.EVENT_TYPE_DISPLAY_STATE,
                                 0));
 
         // test private flags mapping
         assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED,
                 mDisplayManagerGlobal
-                        .mapFlagsToInternalEventFlag(0,
-                                DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED));
+                        .mapFiltersToInternalEventFlag(0,
+                                DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_CONNECTION_CHANGED));
         assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_HDR_SDR_RATIO_CHANGED,
                 mDisplayManagerGlobal
-                        .mapFlagsToInternalEventFlag(0,
-                                DisplayManager.PRIVATE_EVENT_FLAG_HDR_SDR_RATIO_CHANGED));
+                        .mapFiltersToInternalEventFlag(0,
+                                DisplayManager.PRIVATE_EVENT_TYPE_HDR_SDR_RATIO_CHANGED));
         assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED,
                 mDisplayManagerGlobal
-                        .mapFlagsToInternalEventFlag(0,
-                                DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                        .mapFiltersToInternalEventFlag(0,
+                                DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
 
         // Test both public and private flags mapping
         assertEquals(DisplayManagerGlobal.INTERNAL_EVENT_FLAG_DISPLAY_BRIGHTNESS_CHANGED
                         | INTERNAL_EVENT_FLAG_DISPLAY_REFRESH_RATE,
                 mDisplayManagerGlobal
-                        .mapFlagsToInternalEventFlag(
-                                DisplayManager.EVENT_FLAG_DISPLAY_REFRESH_RATE,
-                                DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                        .mapFiltersToInternalEventFlag(
+                                DisplayManager.EVENT_TYPE_DISPLAY_REFRESH_RATE,
+                                DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
     }
 
     private void waitForHandler() {
diff --git a/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt b/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt
index 255d09b..008db5e 100644
--- a/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt
+++ b/core/tests/coretests/src/android/hardware/display/DisplayTopologyTest.kt
@@ -22,6 +22,7 @@
 import android.hardware.display.DisplayTopology.TreeNode.POSITION_LEFT
 import android.hardware.display.DisplayTopology.TreeNode.POSITION_TOP
 import android.hardware.display.DisplayTopology.TreeNode.POSITION_RIGHT
+import android.util.SparseArray
 import android.view.Display
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
@@ -642,13 +643,65 @@
         verifyDisplay(
                 root.children[0], id = 1, width = 30f, height = 30f, POSITION_RIGHT, offset = 10f,
                 noOfChildren = 1)
-        // In the case of corner adjacency, we prefer a left/right attachment.
         verifyDisplay(
                 root.children[0].children[0], id = 2, width = 29.5f, height = 30f, POSITION_BOTTOM,
                 offset = 30f, noOfChildren = 0)
     }
 
     @Test
+    fun rearrange_preferLessShiftInOverlapDimension() {
+        val root = rearrangeRects(
+            // '*' represents overlap
+            // Clamping requires moving display 2 and 1 slightly to avoid overlap with 0. We should
+            // shift the minimal amount to avoid overlap - e.g. display 2 shifts left (10 pixels)
+            // rather than up (20 pixels).
+            // 222
+            // 22*00
+            // 22*00
+            //   0**1
+            //    111
+            //    111
+            RectF(20f, 10f, 50f, 40f),
+            RectF(30f, 30f, 60f, 60f),
+            RectF(0f, 0f, 30f, 30f),
+        )
+
+        verifyDisplay(root, id = 0, width = 30f, height = 30f, noOfChildren = 2)
+        verifyDisplay(
+                root.children[0], id = 1, width = 30f, height = 30f, POSITION_BOTTOM, offset = 10f,
+                noOfChildren = 0)
+        verifyDisplay(
+                root.children[1], id = 2, width = 30f, height = 30f, POSITION_LEFT, offset = -10f,
+                noOfChildren = 0)
+    }
+
+    @Test
+    fun rearrange_doNotAttachCornerForShortOverlapOnLongEdgeBottom() {
+        val root = rearrangeRects(
+            RectF(0f, 0f, 1920f, 1080f),
+            RectF(1850f, 1070f, 3770f, 2150f),
+        )
+
+        verifyDisplay(root, id = 0, width = 1920f, height = 1080f, noOfChildren = 1)
+        verifyDisplay(
+                root.children[0], id = 1, width = 1920f, height = 1080f, POSITION_BOTTOM,
+                offset = 1850f, noOfChildren = 0)
+    }
+
+    @Test
+    fun rearrange_doNotAttachCornerForShortOverlapOnLongEdgeLeft() {
+        val root = rearrangeRects(
+            RectF(0f, 0f, 1080f, 1920f),
+            RectF(-1070f, -1880f, 10f, 40f),
+        )
+
+        verifyDisplay(root, id = 0, width = 1080f, height = 1920f, noOfChildren = 1)
+        verifyDisplay(
+                root.children[0], id = 1, width = 1080f, height = 1920f, POSITION_LEFT,
+                offset = -1880f, noOfChildren = 0)
+    }
+
+    @Test
     fun copy() {
         val display1 = DisplayTopology.TreeNode(/* displayId= */ 1, /* width= */ 200f,
             /* height= */ 600f, /* position= */ 0, /* offset= */ 0f)
@@ -687,6 +740,34 @@
             offset = 0f, noOfChildren = 0)
     }
 
+    @Test
+    fun coordinates() {
+        val display1 = DisplayTopology.TreeNode(/* displayId= */ 1, /* width= */ 200f,
+            /* height= */ 600f, /* position= */ 0, /* offset= */ 0f)
+
+        val display2 = DisplayTopology.TreeNode(/* displayId= */ 2, /* width= */ 600f,
+            /* height= */ 200f, POSITION_RIGHT, /* offset= */ 0f)
+        display1.addChild(display2)
+
+        val display3 = DisplayTopology.TreeNode(/* displayId= */ 3, /* width= */ 600f,
+            /* height= */ 200f, POSITION_RIGHT, /* offset= */ 400f)
+        display1.addChild(display3)
+
+        val display4 = DisplayTopology.TreeNode(/* displayId= */ 4, /* width= */ 200f,
+            /* height= */ 600f, POSITION_RIGHT, /* offset= */ 0f)
+        display2.addChild(display4)
+
+        topology = DisplayTopology(display1, /* primaryDisplayId= */ 1)
+        val coords = topology.absoluteBounds
+
+        val expectedCoords = SparseArray<RectF>()
+        expectedCoords.append(1, RectF(0f, 0f, 200f, 600f))
+        expectedCoords.append(2, RectF(200f, 0f, 800f, 200f))
+        expectedCoords.append(3, RectF(200f, 400f, 800f, 600f))
+        expectedCoords.append(4, RectF(800f, 0f, 1000f, 600f))
+        assertThat(coords.contentEquals(expectedCoords)).isTrue()
+    }
+
     /**
      * Runs the rearrange algorithm and returns the resulting tree as a list of nodes, with the
      * root at index 0. The number of nodes is inferred from the number of positions passed.
diff --git a/core/tests/coretests/src/android/security/advancedprotection/AdvancedProtectionManagerTest.java b/core/tests/coretests/src/android/security/advancedprotection/AdvancedProtectionManagerTest.java
deleted file mode 100644
index 45864b0..0000000
--- a/core/tests/coretests/src/android/security/advancedprotection/AdvancedProtectionManagerTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.security.advancedprotection;
-
-import static android.security.advancedprotection.AdvancedProtectionManager.ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG;
-import static android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_FEATURE;
-import static android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_TYPE;
-import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_CELLULAR_2G;
-import static android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION;
-import static android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_DISABLED_SETTING;
-import static android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_UNKNOWN;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThrows;
-
-import android.content.Intent;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class AdvancedProtectionManagerTest {
-    private static final int FEATURE_ID_INVALID = -1;
-    private static final int SUPPORT_DIALOG_TYPE_INVALID = -1;
-
-    @Test
-    public void testCreateSupportIntent_validFeature_validTypeUnknown_createsIntent() {
-        Intent intent = AdvancedProtectionManager.createSupportIntent(
-                FEATURE_ID_DISALLOW_CELLULAR_2G, SUPPORT_DIALOG_TYPE_UNKNOWN);
-
-        assertEquals(ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG, intent.getAction());
-        assertEquals(FEATURE_ID_DISALLOW_CELLULAR_2G, intent.getIntExtra(
-                EXTRA_SUPPORT_DIALOG_FEATURE, FEATURE_ID_INVALID));
-        assertEquals(SUPPORT_DIALOG_TYPE_UNKNOWN, intent.getIntExtra(EXTRA_SUPPORT_DIALOG_TYPE,
-                SUPPORT_DIALOG_TYPE_INVALID));
-    }
-
-    @Test
-    public void testCreateSupportIntent_validFeature_validTypeBlockedInteraction_createsIntent() {
-        Intent intent = AdvancedProtectionManager.createSupportIntent(
-                FEATURE_ID_DISALLOW_CELLULAR_2G, SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION);
-
-        assertEquals(ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG, intent.getAction());
-        assertEquals(FEATURE_ID_DISALLOW_CELLULAR_2G, intent.getIntExtra(
-                EXTRA_SUPPORT_DIALOG_FEATURE, FEATURE_ID_INVALID));
-        assertEquals(SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION, intent.getIntExtra(
-                EXTRA_SUPPORT_DIALOG_TYPE, SUPPORT_DIALOG_TYPE_INVALID));
-    }
-
-    @Test
-    public void testCreateSupportIntent_validFeature_validTypeDisabledSetting_createsIntent() {
-        Intent intent = AdvancedProtectionManager.createSupportIntent(
-                FEATURE_ID_DISALLOW_CELLULAR_2G, SUPPORT_DIALOG_TYPE_DISABLED_SETTING);
-
-        assertEquals(ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG, intent.getAction());
-        assertEquals(FEATURE_ID_DISALLOW_CELLULAR_2G, intent.getIntExtra(
-                EXTRA_SUPPORT_DIALOG_FEATURE, FEATURE_ID_INVALID));
-        assertEquals(SUPPORT_DIALOG_TYPE_DISABLED_SETTING, intent.getIntExtra(
-                EXTRA_SUPPORT_DIALOG_TYPE, SUPPORT_DIALOG_TYPE_INVALID));
-    }
-
-    @Test
-    public void testCreateSupportIntent_validFeature_invalidType_throwsIllegalArgument() {
-        assertThrows(IllegalArgumentException.class, () ->
-                AdvancedProtectionManager.createSupportIntent(FEATURE_ID_DISALLOW_CELLULAR_2G,
-                        SUPPORT_DIALOG_TYPE_INVALID));
-    }
-
-    @Test
-    public void testCreateSupportIntent_invalidFeature_validType_throwsIllegalArgument() {
-        assertThrows(IllegalArgumentException.class, () ->
-                AdvancedProtectionManager.createSupportIntent(FEATURE_ID_INVALID,
-                        SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION));
-    }
-
-    @Test
-    public void testCreateSupportIntent_invalidFeature_invalidType_throwsIllegalArgument() {
-        assertThrows(IllegalArgumentException.class, () ->
-                AdvancedProtectionManager.createSupportIntent(FEATURE_ID_INVALID,
-                        SUPPORT_DIALOG_TYPE_INVALID));
-    }
-}
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index 248db65..4a54f6b 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -133,7 +133,7 @@
             // Called once through the show flow.
             verify(mController).applyAnimation(
                     eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(true) /* fromIme */,
-                    eq(statsToken));
+                    eq(false) /* skipsCallbacks */, eq(statsToken));
 
             // set control and verify visibility is applied.
             InsetsSourceControl control = new InsetsSourceControl(ID_IME,
@@ -142,10 +142,10 @@
             // IME show animation should be triggered when control becomes available.
             verify(mController).applyAnimation(
                     eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(false) /* fromIme */,
-                    and(not(eq(statsToken)), notNull()));
+                    eq(false) /* skipsCallbacks */, and(not(eq(statsToken)), notNull()));
             verify(mController, never()).applyAnimation(
                     eq(WindowInsets.Type.ime()), eq(false) /* show */, eq(false) /* fromIme */,
-                    and(not(eq(statsToken)), notNull()));
+                    eq(false) /* skipsCallbacks */, and(not(eq(statsToken)), notNull()));
         });
     }
 
@@ -163,7 +163,7 @@
             // Called once through the show flow.
             verify(mController).applyAnimation(
                     eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(true) /* fromIme */,
-                    eq(statsToken));
+                    eq(false) /* skipsCallbacks */, eq(statsToken));
             // Clear previous invocations to verify this is never called with control without leash.
             clearInvocations(mController);
 
@@ -175,10 +175,10 @@
             // as we have no leash.
             verify(mController, never()).applyAnimation(
                     eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(false) /* fromIme */,
-                    and(not(eq(statsToken)), notNull()));
+                    eq(false) /* skipsCallbacks */, and(not(eq(statsToken)), notNull()));
             verify(mController, never()).applyAnimation(
                     eq(WindowInsets.Type.ime()), eq(false) /* show */, eq(false) /* fromIme */,
-                    and(not(eq(statsToken)), notNull()));
+                    eq(false) /* skipsCallbacks */, and(not(eq(statsToken)), notNull()));
 
             // set control with leash and verify visibility is applied.
             InsetsSourceControl controlWithLeash = new InsetsSourceControl(ID_IME,
@@ -187,10 +187,10 @@
             // IME show animation should be triggered when control with leash becomes available.
             verify(mController).applyAnimation(
                     eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(false) /* fromIme */,
-                    and(not(eq(statsToken)), notNull()));
+                    eq(false) /* skipsCallbacks */, and(not(eq(statsToken)), notNull()));
             verify(mController, never()).applyAnimation(
                     eq(WindowInsets.Type.ime()), eq(false) /* show */, eq(false) /* fromIme */,
-                    and(not(eq(statsToken)), notNull()));
+                    eq(false) /* skipsCallbacks */, and(not(eq(statsToken)), notNull()));
         });
     }
 
@@ -223,7 +223,8 @@
                 // Called once through the show flow.
                 verify(mController).applyAnimation(eq(WindowInsets.Type.ime()),
                         eq(true) /* show */, eq(true) /* fromIme */,
-                        eq(false) /* skipAnim */, eq(statsToken));
+                        eq(false) /* skipsAnim */, eq(false) /* skipsCallbacks */,
+                        eq(statsToken));
             }
 
             // set control and verify visibility is applied.
@@ -241,7 +242,8 @@
                 // so the statsToken won't match.
                 verify(mController).applyAnimation(eq(WindowInsets.Type.ime()),
                         eq(true) /* show */, eq(false) /* fromIme */,
-                        eq(expectSkipAnim) /* skipAnim */, and(not(eq(statsToken)), notNull()));
+                        eq(expectSkipAnim) /* skipsAnim */, eq(false) /* skipsCallbacks */,
+                        and(not(eq(statsToken)), notNull()));
             }
 
             // If previously hasViewFocus is false, verify when requesting the IME visible next
@@ -252,14 +254,16 @@
                 // Called once through the show flow.
                 verify(mController).applyAnimation(eq(WindowInsets.Type.ime()),
                         eq(true) /* show */, eq(true) /* fromIme */,
-                        eq(false) /* skipAnim */, eq(statsTokenNext));
+                        eq(false) /* skipsAnim */, eq(false) /* skipsCallbacks */,
+                        eq(statsTokenNext));
                 mController.onControlsChanged(new InsetsSourceControl[]{ control });
                 // Verify IME show animation should be triggered when control becomes available and
                 // the animation will be skipped by getAndClearSkipAnimationOnce invoked.
                 verify(control).getAndClearSkipAnimationOnce();
                 verify(mController).applyAnimation(eq(WindowInsets.Type.ime()),
                         eq(true) /* show */, eq(false) /* fromIme */,
-                        eq(true) /* skipAnim */, and(not(eq(statsToken)), notNull()));
+                        eq(true) /* skipsAnim */, eq(false) /* skipsCallbacks */,
+                        and(not(eq(statsToken)), notNull()));
             }
         });
     }
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index d7f6a29..905d897 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -100,14 +100,14 @@
         topConsumer.setControl(
                 new InsetsSourceControl(ID_STATUS_BAR, WindowInsets.Type.statusBars(),
                         mStatusLeash, true, new Point(0, 0), Insets.of(0, 100, 0, 0)),
-                new int[1], new int[1], new int[1]);
+                new int[1], new int[1], new int[1], new int[1]);
 
         InsetsSourceConsumer navConsumer = new InsetsSourceConsumer(ID_NAVIGATION_BAR,
                 WindowInsets.Type.navigationBars(), mInsetsState, mMockController);
         navConsumer.setControl(
                 new InsetsSourceControl(ID_NAVIGATION_BAR, WindowInsets.Type.navigationBars(),
                         mNavLeash, true, new Point(400, 0), Insets.of(0, 0, 100, 0)),
-                new int[1], new int[1], new int[1]);
+                new int[1], new int[1], new int[1], new int[1]);
         mMockController.setRequestedVisibleTypes(0, WindowInsets.Type.navigationBars());
         navConsumer.applyLocalVisibilityOverride();
 
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index 3a8f7ee..45d66e8 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -117,7 +117,7 @@
         mConsumer.setControl(
                 new InsetsSourceControl(ID_STATUS_BAR, statusBars(), mLeash,
                         true /* initialVisible */, new Point(), Insets.NONE),
-                new int[1], new int[1], new int[1]);
+                new int[1], new int[1], new int[1], new int[1]);
     }
 
     @Test
@@ -129,7 +129,7 @@
             newControl.setInsetsHint(Insets.of(0, 0, 0, 100));
 
             int[] cancelTypes = {0};
-            mConsumer.setControl(newControl, new int[1], new int[1], cancelTypes);
+            mConsumer.setControl(newControl, new int[1], new int[1], cancelTypes, new int[1]);
 
             assertEquals(statusBars(), cancelTypes[0]);
         });
@@ -196,7 +196,7 @@
     @Test
     public void testRestore() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            mConsumer.setControl(null, new int[1], new int[1], new int[1]);
+            mConsumer.setControl(null, new int[1], new int[1], new int[1], new int[1]);
             mSurfaceParamsApplied = false;
             mController.setRequestedVisibleTypes(0 /* visibleTypes */, statusBars());
             assertFalse(mSurfaceParamsApplied);
@@ -204,7 +204,7 @@
             mConsumer.setControl(
                     new InsetsSourceControl(ID_STATUS_BAR, statusBars(), mLeash,
                             true /* initialVisible */, new Point(), Insets.NONE),
-                    new int[1], hideTypes, new int[1]);
+                    new int[1], hideTypes, new int[1], new int[1]);
             assertEquals(statusBars(), hideTypes[0]);
             assertFalse(mRemoveSurfaceCalled);
         });
@@ -214,7 +214,7 @@
     public void testRestore_noAnimation() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             mController.setRequestedVisibleTypes(0 /* visibleTypes */, statusBars());
-            mConsumer.setControl(null, new int[1], new int[1], new int[1]);
+            mConsumer.setControl(null, new int[1], new int[1], new int[1], new int[1]);
             mLeash = new SurfaceControl.Builder(mSession)
                     .setName("testSurface")
                     .build();
@@ -223,7 +223,7 @@
             mConsumer.setControl(
                     new InsetsSourceControl(ID_STATUS_BAR, statusBars(), mLeash,
                             false /* initialVisible */, new Point(), Insets.NONE),
-                    new int[1], hideTypes, new int[1]);
+                    new int[1], hideTypes, new int[1], new int[1]);
             assertTrue(mRemoveSurfaceCalled);
             assertEquals(0, hideTypes[0]);
         });
@@ -252,7 +252,7 @@
             // Initial IME insets source control with its leash.
             imeConsumer.setControl(new InsetsSourceControl(ID_IME, ime(), mLeash,
                     false /* initialVisible */, new Point(), Insets.NONE), new int[1], new int[1],
-                    new int[1]);
+                    new int[1], new int[1]);
             mSurfaceParamsApplied = false;
 
             // Verify when the app requests controlling show IME animation, the IME leash
@@ -262,7 +262,7 @@
             assertEquals(ANIMATION_TYPE_USER, insetsController.getAnimationType(ime()));
             imeConsumer.setControl(new InsetsSourceControl(ID_IME, ime(), mLeash,
                     true /* initialVisible */, new Point(), Insets.NONE), new int[1], new int[1],
-                    new int[1]);
+                    new int[1], new int[1]);
             assertFalse(mSurfaceParamsApplied);
         });
     }
diff --git a/graphics/java/android/graphics/BlendModeColorFilter.java b/graphics/java/android/graphics/BlendModeColorFilter.java
index 7caeb42..d4e2373 100644
--- a/graphics/java/android/graphics/BlendModeColorFilter.java
+++ b/graphics/java/android/graphics/BlendModeColorFilter.java
@@ -71,7 +71,7 @@
             return false;
         }
         final BlendModeColorFilter other = (BlendModeColorFilter) object;
-        return other.mMode == mMode;
+        return (other.mMode == mMode && other.mColor == mColor);
     }
 
     @Override
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/RearDisplayPresentationRequestCallback.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/RearDisplayPresentationRequestCallback.java
index ea33426..9f978e0 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/RearDisplayPresentationRequestCallback.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/RearDisplayPresentationRequestCallback.java
@@ -43,10 +43,7 @@
     public RearDisplayPresentationRequestCallback(@NonNull Context context,
             @NonNull RearDisplayPresentationController rearDisplayPresentationController) {
         mDisplayManager = context.getSystemService(DisplayManager.class);
-        mDisplayManager.registerDisplayListener(mRearDisplayListener,
-                context.getMainThreadHandler(), DisplayManager.EVENT_FLAG_DISPLAY_ADDED
-                        | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED);
-
+        registerDisplayListener(context);
         mRearDisplayPresentationController = rearDisplayPresentationController;
     }
 
@@ -112,4 +109,10 @@
             mRearDisplayPresentationController.startSession(rearDisplay);
         }
     }
+
+    private void registerDisplayListener(Context context) {
+        mDisplayManager.registerDisplayListener(mRearDisplayListener,
+                context.getMainThreadHandler(), DisplayManager.EVENT_TYPE_DISPLAY_ADDED
+                        | DisplayManager.EVENT_TYPE_DISPLAY_CHANGED);
+    }
 }
diff --git a/libs/WindowManager/Shell/multivalentTests/AndroidManifest.xml b/libs/WindowManager/Shell/multivalentTests/AndroidManifest.xml
index f8f8338..fd578a9 100644
--- a/libs/WindowManager/Shell/multivalentTests/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/multivalentTests/AndroidManifest.xml
@@ -3,6 +3,8 @@
 
     <application android:debuggable="true" android:supportsRtl="true" >
         <uses-library android:name="android.test.runner" />
+        <activity android:name="com.android.wm.shell.bubbles.bar.BubbleBarAnimationHelperTest$TestActivity"
+            android:exported="true"/>
     </application>
 
     <instrumentation
diff --git a/libs/WindowManager/Shell/multivalentTests/AndroidManifestRobolectric.xml b/libs/WindowManager/Shell/multivalentTests/AndroidManifestRobolectric.xml
index ffcd7d4..bb111db 100644
--- a/libs/WindowManager/Shell/multivalentTests/AndroidManifestRobolectric.xml
+++ b/libs/WindowManager/Shell/multivalentTests/AndroidManifestRobolectric.xml
@@ -1,3 +1,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.wm.shell.multivalenttests">
+    <application>
+        <activity android:name="com.android.wm.shell.bubbles.bar.BubbleBarAnimationHelperTest$TestActivity"
+            android:exported="true"/>
+    </application>
 </manifest>
+
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt
index 2b4e541..c62d2a0 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt
@@ -35,11 +35,11 @@
 import com.android.wm.shell.Flags
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.TestShellExecutor
-import com.android.wm.shell.WindowManagerShellWrapper
 import com.android.wm.shell.bubbles.Bubbles.SysuiProxy
 import com.android.wm.shell.bubbles.properties.ProdBubbleProperties
 import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
 import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayImeController
 import com.android.wm.shell.common.DisplayInsetsController
 import com.android.wm.shell.common.FloatingContentCoordinator
 import com.android.wm.shell.common.SyncTransactionQueue
@@ -268,7 +268,8 @@
             bubbleDataRepository,
             mock<IStatusBarService>(),
             mock<WindowManager>(),
-            WindowManagerShellWrapper(mainExecutor),
+            mock<DisplayInsetsController>(),
+            mock<DisplayImeController>(),
             mock<UserManager>(),
             mock<LauncherApps>(),
             bubbleLogger,
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt
index 680d015..3043e2b 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt
@@ -36,10 +36,10 @@
 import com.android.launcher3.icons.BubbleIconFactory
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.TestShellExecutor
-import com.android.wm.shell.WindowManagerShellWrapper
 import com.android.wm.shell.bubbles.properties.BubbleProperties
 import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
 import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayImeController
 import com.android.wm.shell.common.DisplayInsetsController
 import com.android.wm.shell.common.FloatingContentCoordinator
 import com.android.wm.shell.common.SyncTransactionQueue
@@ -141,7 +141,8 @@
                 bubbleDataRepository,
                 mock<IStatusBarService>(),
                 windowManager,
-                WindowManagerShellWrapper(mainExecutor),
+                mock<DisplayInsetsController>(),
+                mock<DisplayImeController>(),
                 mock<UserManager>(),
                 mock<LauncherApps>(),
                 bubbleLogger,
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt
index 3e01256..957f0ca 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt
@@ -17,14 +17,19 @@
 package com.android.wm.shell.bubbles.bar
 
 import android.animation.AnimatorTestRule
+import android.app.Activity
 import android.app.ActivityManager
 import android.content.Context
 import android.graphics.Insets
+import android.graphics.Outline
 import android.graphics.Rect
+import android.os.Bundle
 import android.view.View
 import android.view.ViewGroup
 import android.view.WindowManager
 import android.widget.FrameLayout
+import android.widget.FrameLayout.LayoutParams
+import androidx.test.core.app.ActivityScenario
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -63,6 +68,7 @@
 class BubbleBarAnimationHelperTest {
 
     @get:Rule val animatorTestRule: AnimatorTestRule = AnimatorTestRule(this)
+    private lateinit var activityScenario: ActivityScenario<TestActivity>
 
     companion object {
         const val SCREEN_WIDTH = 2000
@@ -83,6 +89,8 @@
     fun setUp() {
         ProtoLog.REQUIRE_PROTOLOGTOOL = false
         ProtoLog.init()
+        activityScenario = ActivityScenario.launch(TestActivity::class.java)
+        activityScenario.onActivity { activity -> container = activity.container }
         val windowManager = context.getSystemService(WindowManager::class.java)
         bubblePositioner = BubblePositioner(context, windowManager)
         bubblePositioner.setShowingInBubbleBar(true)
@@ -102,8 +110,6 @@
         mainExecutor = TestShellExecutor()
         bgExecutor = TestShellExecutor()
 
-        container = FrameLayout(context)
-
         animationHelper = BubbleBarAnimationHelper(context, bubblePositioner)
     }
 
@@ -121,7 +127,7 @@
         val semaphore = Semaphore(0)
         val after = Runnable { semaphore.release() }
 
-        getInstrumentation().runOnMainSync {
+        activityScenario.onActivity {
             animationHelper.animateSwitch(fromBubble, toBubble, after)
             animatorTestRule.advanceTimeBy(1000)
         }
@@ -145,7 +151,7 @@
             .updateHandleColor(/* isRegionDark= */ true, /* animated= */ false)
         val toBubble = createBubble(key = "to").initialize(container)
 
-        getInstrumentation().runOnMainSync {
+        activityScenario.onActivity {
             animationHelper.animateSwitch(fromBubble, toBubble, /* afterAnimation= */ null)
             animatorTestRule.advanceTimeBy(1000)
         }
@@ -161,7 +167,7 @@
         val toBubbleTaskController = mock<TaskViewTaskController>()
         val toBubble = createBubble("to", toBubbleTaskController).initialize(container)
 
-        getInstrumentation().runOnMainSync {
+        activityScenario.onActivity {
             animationHelper.animateSwitch(fromBubble, toBubble) {}
             // Start the animation, but don't finish
             animatorTestRule.advanceTimeBy(100)
@@ -183,7 +189,7 @@
         val semaphore = Semaphore(0)
         val after = Runnable { semaphore.release() }
 
-        getInstrumentation().runOnMainSync {
+        activityScenario.onActivity {
             animationHelper.animateSwitch(fromBubble, overflow, after)
             animatorTestRule.advanceTimeBy(1000)
         }
@@ -206,7 +212,7 @@
         val semaphore = Semaphore(0)
         val after = Runnable { semaphore.release() }
 
-        getInstrumentation().runOnMainSync {
+        activityScenario.onActivity {
             animationHelper.animateSwitch(overflow, toBubble, after)
             animatorTestRule.advanceTimeBy(1000)
         }
@@ -226,7 +232,7 @@
         val taskController = mock<TaskViewTaskController>()
         val bubble = createBubble("key", taskController).initialize(container)
 
-        getInstrumentation().runOnMainSync {
+        activityScenario.onActivity {
             animationHelper.animateExpansion(bubble) {}
             animatorTestRule.advanceTimeBy(1000)
         }
@@ -243,6 +249,80 @@
         verify(taskController).setWindowBounds(any())
     }
 
+    @Test
+    fun animateExpansion() {
+        val bubble = createBubble(key = "b1").initialize(container)
+        val bbev = bubble.bubbleBarExpandedView!!
+
+        val semaphore = Semaphore(0)
+        val after = Runnable { semaphore.release() }
+
+        activityScenario.onActivity {
+            bbev.onTaskCreated()
+            animationHelper.animateExpansion(bubble, after)
+            animatorTestRule.advanceTimeBy(1000)
+        }
+        getInstrumentation().waitForIdleSync()
+
+        assertThat(semaphore.tryAcquire(5, TimeUnit.SECONDS)).isTrue()
+        assertThat(bbev.alpha).isEqualTo(1)
+    }
+
+    @Test
+    fun onImeTopChanged_noOverlap() {
+        val bubble = createBubble(key = "b1").initialize(container)
+        val bbev = bubble.bubbleBarExpandedView!!
+
+        val semaphore = Semaphore(0)
+        val after = Runnable { semaphore.release() }
+
+        activityScenario.onActivity {
+            bbev.onTaskCreated()
+            animationHelper.animateExpansion(bubble, after)
+            animatorTestRule.advanceTimeBy(1000)
+        }
+        getInstrumentation().waitForIdleSync()
+
+        assertThat(semaphore.tryAcquire(5, TimeUnit.SECONDS)).isTrue()
+
+        val bbevBottom = bbev.contentBottomOnScreen + bubblePositioner.insets.top
+        activityScenario.onActivity {
+            // notify that the IME top coordinate is greater than the bottom of the expanded view.
+            // there's no overlap so it should not be clipped.
+            animationHelper.onImeTopChanged(bbevBottom * 2)
+        }
+        val outline = Outline()
+        bbev.outlineProvider.getOutline(bbev, outline)
+        assertThat(outline.mRect.bottom).isEqualTo(bbev.height)
+    }
+
+    @Test
+    fun onImeTopChanged_overlapsWithExpandedView() {
+        val bubble = createBubble(key = "b1").initialize(container)
+        val bbev = bubble.bubbleBarExpandedView!!
+
+        val semaphore = Semaphore(0)
+        val after = Runnable { semaphore.release() }
+
+        activityScenario.onActivity {
+            bbev.onTaskCreated()
+            animationHelper.animateExpansion(bubble, after)
+            animatorTestRule.advanceTimeBy(1000)
+        }
+        getInstrumentation().waitForIdleSync()
+
+        assertThat(semaphore.tryAcquire(5, TimeUnit.SECONDS)).isTrue()
+
+        activityScenario.onActivity {
+            // notify that the IME top coordinate is less than the bottom of the expanded view,
+            // meaning it overlaps with it so we should be clipping the expanded view.
+            animationHelper.onImeTopChanged(bbev.contentBottomOnScreen - 10)
+        }
+        val outline = Outline()
+        bbev.outlineProvider.getOutline(bbev, outline)
+        assertThat(outline.mRect.bottom).isEqualTo(bbev.height - 10)
+    }
+
     private fun createBubble(
         key: String,
         taskViewTaskController: TaskViewTaskController = mock<TaskViewTaskController>(),
@@ -273,14 +353,24 @@
     }
 
     private fun Bubble.initialize(container: ViewGroup): Bubble {
-        getInstrumentation().runOnMainSync { container.addView(bubbleBarExpandedView) }
+        activityScenario.onActivity { container.addView(bubbleBarExpandedView) }
         // Mark taskView's visible
         bubbleBarExpandedView!!.onContentVisibilityChanged(true)
         return this
     }
 
     private fun BubbleOverflow.initialize(container: ViewGroup): BubbleOverflow {
-        getInstrumentation().runOnMainSync { container.addView(bubbleBarExpandedView) }
+        activityScenario.onActivity { container.addView(bubbleBarExpandedView) }
         return this
     }
+
+    class TestActivity : Activity() {
+        lateinit var container: FrameLayout
+        override fun onCreate(savedInstanceState: Bundle?) {
+            super.onCreate(savedInstanceState)
+            container = FrameLayout(applicationContext)
+            container.layoutParams = LayoutParams(50, 50)
+            setContentView(container)
+        }
+    }
 }
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
index 5c86b32..9b1645e 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
@@ -37,7 +37,6 @@
 import com.android.wm.shell.R
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.TestShellExecutor
-import com.android.wm.shell.WindowManagerShellWrapper
 import com.android.wm.shell.bubbles.Bubble
 import com.android.wm.shell.bubbles.BubbleController
 import com.android.wm.shell.bubbles.BubbleData
@@ -54,6 +53,7 @@
 import com.android.wm.shell.bubbles.properties.BubbleProperties
 import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
 import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayImeController
 import com.android.wm.shell.common.DisplayInsetsController
 import com.android.wm.shell.common.FloatingContentCoordinator
 import com.android.wm.shell.common.SyncTransactionQueue
@@ -180,7 +180,8 @@
             bubbleDataRepository,
             mock<IStatusBarService>(),
             windowManager,
-            WindowManagerShellWrapper(mainExecutor),
+            mock<DisplayInsetsController>(),
+            mock<DisplayImeController>(),
             mock<UserManager>(),
             mock<LauncherApps>(),
             bubbleLogger,
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 07cc0e7..a975682 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -34,8 +34,8 @@
     <string name="dock_forced_resizable" msgid="7429086980048964687">"App sal dalk nie met verdeelde skerm werk nie"</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"App steun nie verdeelde skerm nie"</string>
     <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Hierdie app kan net in 1 venster oopgemaak word"</string>
-    <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Program sal dalk nie op \'n sekondêre skerm werk nie."</string>
-    <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Program steun nie begin op sekondêre skerms nie."</string>
+    <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App sal dalk nie op \'n sekondêre skerm werk nie."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App steun nie begin op sekondêre skerms nie."</string>
     <string name="accessibility_divider" msgid="6407584574218956849">"Skermverdeler"</string>
     <string name="divider_title" msgid="1963391955593749442">"Skermverdeler"</string>
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Volskerm links"</string>
@@ -78,7 +78,7 @@
     <string name="bubbles_user_education_title" msgid="2112319053732691899">"Klets met borrels"</string>
     <string name="bubbles_user_education_description" msgid="4215862563054175407">"Nuwe gesprekke verskyn as swerwende ikone, of borrels Tik op borrel om dit oop te maak. Sleep om dit te skuif."</string>
     <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Beheer borrels enige tyd"</string>
-    <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Tik op Bestuur om borrels vanaf hierdie program af te skakel"</string>
+    <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Tik op Bestuur om borrels vanaf hierdie app af te skakel"</string>
     <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Het dit"</string>
     <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Geen onlangse borrels nie"</string>
     <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Onlangse borrels en borrels wat toegemaak is, sal hier verskyn"</string>
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 9aba3aa..8efeecb 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
@@ -90,13 +90,15 @@
 import com.android.wm.shell.Flags;
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
 import com.android.wm.shell.bubbles.properties.BubbleProperties;
 import com.android.wm.shell.bubbles.shortcut.BubbleShortcutHelper;
 import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.DisplayInsetsController;
 import com.android.wm.shell.common.ExternalInterfaceBinder;
 import com.android.wm.shell.common.FloatingContentCoordinator;
+import com.android.wm.shell.common.ImeListener;
 import com.android.wm.shell.common.RemoteCallable;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SingleInstanceRemoteListener;
@@ -106,7 +108,6 @@
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.onehanded.OneHandedController;
 import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
-import com.android.wm.shell.pip.PinnedStackListenerForwarder;
 import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
 import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
@@ -182,7 +183,8 @@
     @Nullable private final BubbleStackView.SurfaceSynchronizer mSurfaceSynchronizer;
     private final FloatingContentCoordinator mFloatingContentCoordinator;
     private final BubbleDataRepository mDataRepository;
-    private final WindowManagerShellWrapper mWindowManagerShellWrapper;
+    private final DisplayInsetsController mDisplayInsetsController;
+    private final DisplayImeController mDisplayImeController;
     private final UserManager mUserManager;
     private final LauncherApps mLauncherApps;
     private final IStatusBarService mBarService;
@@ -291,7 +293,8 @@
             BubbleDataRepository dataRepository,
             @Nullable IStatusBarService statusBarService,
             WindowManager windowManager,
-            WindowManagerShellWrapper windowManagerShellWrapper,
+            DisplayInsetsController displayInsetsController,
+            DisplayImeController displayImeController,
             UserManager userManager,
             LauncherApps launcherApps,
             BubbleLogger bubbleLogger,
@@ -318,7 +321,8 @@
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE))
                 : statusBarService;
         mWindowManager = windowManager;
-        mWindowManagerShellWrapper = windowManagerShellWrapper;
+        mDisplayInsetsController = displayInsetsController;
+        mDisplayImeController = displayImeController;
         mUserManager = userManager;
         mFloatingContentCoordinator = floatingContentCoordinator;
         mDataRepository = dataRepository;
@@ -403,11 +407,15 @@
             mMainExecutor.execute(() -> removeBubble(bubble.getKey(), DISMISS_INVALID_INTENT));
         });
 
-        try {
-            mWindowManagerShellWrapper.addPinnedStackListener(new BubblesImeListener());
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
+        BubblesImeListener bubblesImeListener =
+                new BubblesImeListener(mDisplayController, mContext.getDisplayId());
+        // the insets controller is notified whenever the IME visibility changes whether the IME is
+        // requested by a bubbled task or non-bubbled task. in the latter case, we need to update
+        // the position of the stack to avoid overlapping with the IME.
+        mDisplayInsetsController.addInsetsChangedListener(mContext.getDisplayId(),
+                bubblesImeListener);
+        // the ime controller is notified when the IME is requested only by a bubbled task.
+        mDisplayImeController.addPositionProcessor(bubblesImeListener);
 
         mBubbleData.setCurrentUserId(mCurrentUserId);
 
@@ -1441,6 +1449,15 @@
     }
 
     /**
+     * Expands and selects a bubble created from a running task in a different mode.
+     *
+     * @param taskInfo the task.
+     */
+    public void expandStackAndSelectBubble(ActivityManager.RunningTaskInfo taskInfo) {
+        // TODO(384976265): Not implemented yet
+    }
+
+    /**
      * Expands and selects a bubble based on the provided {@link BubbleEntry}. If no bubble
      * exists for this entry, and it is able to bubble, a new bubble will be created.
      *
@@ -2515,16 +2532,57 @@
         return contextForUser.getPackageManager();
     }
 
-    /** PinnedStackListener that dispatches IME visibility updates to the stack. */
-    //TODO(b/170442945): Better way to do this / insets listener?
-    private class BubblesImeListener extends PinnedStackListenerForwarder.PinnedTaskListener {
+    /** {@link ImeListener} that dispatches IME visibility updates to the stack. */
+    private class BubblesImeListener extends ImeListener implements
+            DisplayImeController.ImePositionProcessor {
+
+        BubblesImeListener(DisplayController displayController, int displayId) {
+            super(displayController, displayId);
+        }
+
         @Override
-        public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
-            mBubblePositioner.setImeVisible(imeVisible, imeHeight);
+        protected void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
+            if (getDisplayId() != mContext.getDisplayId()) {
+                return;
+            }
+            // the imeHeight here is actually the ime inset; it only includes the part of the ime
+            // that overlaps with the Bubbles window. adjust it to include the bottom screen inset,
+            // so we have the total height of the ime.
+            int totalImeHeight = imeHeight + mBubblePositioner.getInsets().bottom;
+            mBubblePositioner.setImeVisible(imeVisible, totalImeHeight);
             if (mStackView != null) {
                 mStackView.setImeVisible(imeVisible);
             }
         }
+
+        @Override
+        public int onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
+                boolean showing, boolean isFloating, SurfaceControl.Transaction t) {
+            if (mContext.getDisplayId() != displayId) {
+                return IME_ANIMATION_DEFAULT;
+            }
+
+            if (showing) {
+                mBubblePositioner.setImeVisible(true, hiddenTop - shownTop);
+            } else {
+                mBubblePositioner.setImeVisible(false, 0);
+            }
+            if (mStackView != null) {
+                mStackView.setImeVisible(showing);
+            }
+
+            return IME_ANIMATION_DEFAULT;
+        }
+
+        @Override
+        public void onImePositionChanged(int displayId, int imeTop, SurfaceControl.Transaction t) {
+            if (mContext.getDisplayId() != displayId) {
+                return;
+            }
+            if (mLayerView != null) {
+                mLayerView.onImeTopChanged(imeTop);
+            }
+        }
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index de85d9a..1a61793 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -67,6 +67,11 @@
     private @Surface.Rotation int mRotation = Surface.ROTATION_0;
     private Insets mInsets;
     private boolean mImeVisible;
+    /**
+     * The height of the IME excluding the bottom inset. If the IME is 100 pixels tall and we have
+     * 20 pixels bottom inset, the IME height is adjusted to 80 to represent the overlap with the
+     * Bubbles window.
+     */
     private int mImeHeight;
     private Rect mPositionRect;
     private int mDefaultMaxBubbles;
@@ -336,10 +341,16 @@
         return mImeVisible;
     }
 
-    /** Sets whether the IME is visible. **/
+    /**
+     * Sets whether the IME is visible and its height.
+     *
+     * @param visible whether the IME is visible
+     * @param height the total height of the IME from the bottom of the physical screen
+     **/
     public void setImeVisible(boolean visible, int height) {
         mImeVisible = visible;
-        mImeHeight = height;
+        // adjust the IME to account for the height as seen by the Bubbles window
+        mImeHeight = visible ? Math.max(height - getInsets().bottom, 0) : 0;
     }
 
     private int getExpandedViewLargeScreenInsetFurthestEdge(boolean isOverflow) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
index 3188e5b..de6d1f6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
@@ -30,6 +30,8 @@
 import static com.android.wm.shell.shared.animation.Interpolators.EMPHASIZED;
 import static com.android.wm.shell.shared.animation.Interpolators.EMPHASIZED_DECELERATE;
 
+import static java.lang.Math.max;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
@@ -375,7 +377,6 @@
         return animator;
     }
 
-
     /**
      * Animate the expanded bubble when it is being dragged
      */
@@ -586,6 +587,18 @@
         }
     }
 
+    /** Handles IME position changes. */
+    public void onImeTopChanged(int imeTop) {
+        BubbleBarExpandedView bbev = getExpandedView();
+        if (bbev == null) {
+            Log.w(TAG, "Bubble bar expanded view was null when IME top changed");
+            return;
+        }
+        int bbevBottom = bbev.getContentBottomOnScreen();
+        int clip = max(bbevBottom - imeTop, 0);
+        bbev.updateBottomClip(clip);
+    }
+
     private @Nullable BubbleBarExpandedView getExpandedView() {
         BubbleViewProvider bubble = mExpandedBubble;
         if (bubble != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index 65c929a..e073b02 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -137,6 +137,7 @@
     private Executor mBackgroundExecutor;
     private final Rect mSampleRect = new Rect();
     private final int[] mLoc = new int[2];
+    private final Rect mTempBounds = new Rect();
 
     /** Height of the caption inset at the top of the TaskView */
     private int mCaptionHeight;
@@ -161,6 +162,9 @@
     private boolean mIsAnimating;
     private boolean mIsDragging;
 
+    private boolean mIsClipping = false;
+    private int mBottomClip = 0;
+
     /** An enum value that tracks the visibility state of the task view */
     private enum TaskViewVisibilityState {
         /** The task view is going away, and we're waiting for the surface to be destroyed. */
@@ -203,7 +207,8 @@
         setOutlineProvider(new ViewOutlineProvider() {
             @Override
             public void getOutline(View view, Outline outline) {
-                outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), mCurrentCornerRadius);
+                outline.setRoundRect(0, 0, view.getWidth(), view.getHeight() - mBottomClip,
+                        mCurrentCornerRadius);
             }
         });
         // Set a touch sink to ensure that clicks on the caption area do not propagate to the parent
@@ -661,6 +666,52 @@
         }
     }
 
+    /** The y coordinate of the bottom of the expanded view. */
+    public int getContentBottomOnScreen() {
+        if (mOverflowView != null) {
+            mOverflowView.getBoundsOnScreen(mTempBounds);
+        }
+        if (mTaskView != null) {
+            mTaskView.getBoundsOnScreen(mTempBounds);
+        }
+        // return the bottom of the content rect, adjusted for insets so the result is in screen
+        // coordinate
+        return mTempBounds.bottom + mPositioner.getInsets().top;
+    }
+
+    /** Update the amount by which to clip the expanded view at the bottom. */
+    public void updateBottomClip(int bottomClip) {
+        mBottomClip = bottomClip;
+        onClipUpdate();
+    }
+
+    private void onClipUpdate() {
+        if (mBottomClip == 0) {
+            if (mIsClipping) {
+                mIsClipping = false;
+                if (mTaskView != null) {
+                    mTaskView.setClipBounds(null);
+                    mTaskView.setEnableSurfaceClipping(false);
+                }
+                invalidateOutline();
+            }
+        } else {
+            if (!mIsClipping) {
+                mIsClipping = true;
+                if (mTaskView != null) {
+                    mTaskView.setEnableSurfaceClipping(true);
+                }
+            }
+            invalidateOutline();
+            if (mTaskView != null) {
+                Rect clipBounds = new Rect(0, 0,
+                        mTaskView.getWidth(),
+                        mTaskView.getHeight() - mBottomClip);
+                mTaskView.setClipBounds(clipBounds);
+            }
+        }
+    }
+
     private void recreateRegionSamplingHelper() {
         if (mRegionSamplingHelper != null) {
             mRegionSamplingHelper.stopAndDestroy();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index 88f34f3..eaa0bd2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -424,6 +424,13 @@
         }
     }
 
+    /** Handles IME position changes. */
+    public void onImeTopChanged(int imeTop) {
+        if (mIsExpanded) {
+            mAnimationHelper.onImeTopChanged(imeTop);
+        }
+    }
+
     /**
      * Log the event only if {@link #mExpandedBubble} is a {@link Bubble}.
      * <p>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index 9ebb7f5..eb1e727 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -419,8 +419,12 @@
                 // already (e.g., when focussing an editText in activity B, while and editText in
                 // activity A is focussed), we will not get a call of #insetsControlChanged, and
                 // therefore have to start the show animation from here
-                startAnimation(mImeRequestedVisible /* show */, false /* forceRestart */,
-                        statsToken);
+                if (visible || mImeShowing) {
+                    // only start the animation if we're either already showing or becoming visible.
+                    // otherwise starting another hide animation causes flickers.
+                    startAnimation(mImeRequestedVisible /* show */, false /* forceRestart */,
+                            statsToken);
+                }
 
                 // In case of a hide, the statsToken should not been send yet (as the animation
                 // is still ongoing). It will be sent at the end of the animation
@@ -723,6 +727,10 @@
      * Allows other things to synchronize with the ime position
      */
     public interface ImePositionProcessor {
+
+        /** Default animation flags. */
+        int IME_ANIMATION_DEFAULT = 0;
+
         /**
          * Indicates that ime shouldn't animate alpha. It will always be opaque. Used when stuff
          * behind the IME shouldn't be visible (for example during split-screen adjustment where
@@ -732,6 +740,7 @@
 
         /** @hide */
         @IntDef(prefix = {"IME_ANIMATION_"}, value = {
+                IME_ANIMATION_DEFAULT,
                 IME_ANIMATION_NO_ALPHA,
         })
         @interface ImeAnimationFlags {
@@ -758,7 +767,7 @@
         @ImeAnimationFlags
         default int onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
                 boolean showing, boolean isFloating, SurfaceControl.Transaction t) {
-            return 0;
+            return IME_ANIMATION_DEFAULT;
         }
 
         /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ImeListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ImeListener.kt
index a34d7be..8851b6a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ImeListener.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ImeListener.kt
@@ -22,8 +22,8 @@
 import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener
 
 abstract class ImeListener(
-    private val mDisplayController: DisplayController,
-    private val mDisplayId: Int
+    private val displayController: DisplayController,
+    val displayId: Int
 ) : OnInsetsChangedListener {
     // The last insets state
     private val mInsetsState = InsetsState()
@@ -36,17 +36,11 @@
 
         // Get the stable bounds that account for display cutout and system bars to calculate the
         // relative IME height
-        val layout = mDisplayController.getDisplayLayout(mDisplayId)
-        if (layout == null) {
-            return
-        }
+        val layout = displayController.getDisplayLayout(displayId) ?: return
         layout.getStableBounds(mTmpBounds)
 
-        val wasVisible = getImeVisibilityAndHeight(mInsetsState).first
-        val oldHeight = getImeVisibilityAndHeight(mInsetsState).second
-
-        val isVisible = getImeVisibilityAndHeight(insetsState).first
-        val newHeight = getImeVisibilityAndHeight(insetsState).second
+        val (wasVisible, oldHeight) = getImeVisibilityAndHeight(mInsetsState)
+        val (isVisible, newHeight) = getImeVisibilityAndHeight(insetsState)
 
         mInsetsState.set(insetsState, true)
         if (wasVisible != isVisible || oldHeight != newHeight) {
@@ -54,8 +48,7 @@
         }
     }
 
-    private fun getImeVisibilityAndHeight(
-            insetsState: InsetsState): Pair<Boolean, Int> {
+    private fun getImeVisibilityAndHeight(insetsState: InsetsState): Pair<Boolean, Int> {
         val source = insetsState.peekSource(InsetsSource.ID_IME)
         val frame = if (source != null && source.isVisible) source.frame else null
         val height = if (frame != null) mTmpBounds.bottom - frame.top else 0
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index eab7f6c..1408b6e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -124,6 +124,7 @@
 import com.android.wm.shell.sysui.ShellInterface;
 import com.android.wm.shell.taskview.TaskViewFactory;
 import com.android.wm.shell.taskview.TaskViewFactoryController;
+import com.android.wm.shell.taskview.TaskViewRepository;
 import com.android.wm.shell.taskview.TaskViewTransitions;
 import com.android.wm.shell.transition.FocusTransitionObserver;
 import com.android.wm.shell.transition.HomeTransitionObserver;
@@ -772,8 +773,15 @@
 
     @WMSingleton
     @Provides
-    static TaskViewTransitions provideTaskViewTransitions(Transitions transitions) {
-        return new TaskViewTransitions(transitions);
+    static TaskViewTransitions provideTaskViewTransitions(Transitions transitions,
+            TaskViewRepository repository) {
+        return new TaskViewTransitions(transitions, repository);
+    }
+
+    @WMSingleton
+    @Provides
+    static TaskViewRepository provideTaskViewRepository() {
+        return new TaskViewRepository();
     }
 
     // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index d02c6b0..48b0a6c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -47,7 +47,6 @@
 import com.android.window.flags.Flags;
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
 import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
 import com.android.wm.shell.apptoweb.AppToWebGenericLinksParser;
 import com.android.wm.shell.apptoweb.AssistContentRequester;
@@ -233,7 +232,8 @@
             FloatingContentCoordinator floatingContentCoordinator,
             IStatusBarService statusBarService,
             WindowManager windowManager,
-            WindowManagerShellWrapper windowManagerShellWrapper,
+            DisplayInsetsController displayInsetsController,
+            DisplayImeController displayImeController,
             UserManager userManager,
             LauncherApps launcherApps,
             TaskStackListenerImpl taskStackListener,
@@ -265,7 +265,8 @@
                         new BubblePersistentRepository(context)),
                 statusBarService,
                 windowManager,
-                windowManagerShellWrapper,
+                displayInsetsController,
+                displayImeController,
                 userManager,
                 launcherApps,
                 logger,
@@ -735,7 +736,8 @@
             DesktopModeEventLogger desktopModeEventLogger,
             DesktopModeUiEventLogger desktopModeUiEventLogger,
             DesktopTilingDecorViewModel desktopTilingDecorViewModel,
-            DesktopWallpaperActivityTokenProvider desktopWallpaperActivityTokenProvider) {
+            DesktopWallpaperActivityTokenProvider desktopWallpaperActivityTokenProvider,
+            Optional<BubbleController> bubbleController) {
         return new DesktopTasksController(
                 context,
                 shellInit,
@@ -767,7 +769,8 @@
                 desktopModeEventLogger,
                 desktopModeUiEventLogger,
                 desktopTilingDecorViewModel,
-                desktopWallpaperActivityTokenProvider);
+                desktopWallpaperActivityTokenProvider,
+                bubbleController);
     }
 
     @WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 4e7cba2..d180ea7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -73,6 +73,7 @@
 import com.android.wm.shell.R
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.bubbles.BubbleController
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayLayout
 import com.android.wm.shell.common.ExternalInterfaceBinder
@@ -172,6 +173,7 @@
     private val desktopModeUiEventLogger: DesktopModeUiEventLogger,
     private val desktopTilingDecorViewModel: DesktopTilingDecorViewModel,
     private val desktopWallpaperActivityTokenProvider: DesktopWallpaperActivityTokenProvider,
+    private val bubbleController: Optional<BubbleController>,
 ) :
     RemoteCallable<DesktopTasksController>,
     Transitions.TransitionHandler,
@@ -2190,6 +2192,19 @@
         }
     }
 
+    /** Requests a task be transitioned from whatever mode it's in to a bubble. */
+    fun requestFloat(taskInfo: RunningTaskInfo) {
+        val isDragging = dragToDesktopTransitionHandler.inProgress
+        val shouldRequestFloat =
+            taskInfo.isFullscreen || taskInfo.isFreeform || isDragging || taskInfo.isMultiWindow
+        if (!shouldRequestFloat) return
+        if (isDragging) {
+            releaseVisualIndicator()
+        } else {
+            bubbleController.ifPresent { it.expandStackAndSelectBubble(taskInfo) }
+        }
+    }
+
     private fun getDefaultDensityDpi(): Int {
         return context.resources.displayMetrics.densityDpi
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt
index f6ebf72..6e12bf4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/ToggleTaskSizeUtils.kt
@@ -90,10 +90,10 @@
             Source.HEADER_BUTTON_TO_RESTORE -> Cuj.CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW
             Source.KEYBOARD_SHORTCUT -> null
             Source.HEADER_DRAG_TO_TOP -> null
-            Source.MAXIMIZE_MENU_TO_MAXIMIZE -> null
-            Source.MAXIMIZE_MENU_TO_RESTORE -> null
-            Source.DOUBLE_TAP_TO_MAXIMIZE -> null
-            Source.DOUBLE_TAP_TO_RESTORE -> null
+            Source.MAXIMIZE_MENU_TO_MAXIMIZE -> Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW
+            Source.MAXIMIZE_MENU_TO_RESTORE -> Cuj.CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW
+            Source.DOUBLE_TAP_TO_MAXIMIZE -> Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW
+            Source.DOUBLE_TAP_TO_RESTORE -> Cuj.CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW
         }
 
     /** The direction to which the task is being resized. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
index fd387d1..3729653 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
@@ -350,7 +350,7 @@
         }
         cancelPhysicsAnimation();
         mMenuController.hideMenu(ANIM_TYPE_DISMISS, false /* resize */);
-        mPipScheduler.removePipAfterAnimation();
+        mPipScheduler.scheduleRemovePip();
     }
 
     /** Sets the movement bounds to use to constrain PIP position animations. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
index 4461a5c..7f673d2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
@@ -122,34 +122,26 @@
      * Schedules exit PiP via expand transition.
      */
     public void scheduleExitPipViaExpand() {
-        WindowContainerTransaction wct = getExitPipViaExpandTransaction();
-        if (wct != null) {
-            mMainExecutor.execute(() -> {
+        mMainExecutor.execute(() -> {
+            if (!mPipTransitionState.isInPip()) return;
+            WindowContainerTransaction wct = getExitPipViaExpandTransaction();
+            if (wct != null) {
                 mPipTransitionController.startExitTransition(TRANSIT_EXIT_PIP, wct,
                         null /* destinationBounds */);
-            });
-        }
-    }
-
-    // TODO: Optimize this by running the animation as part of the transition
-    /** Runs remove PiP animation and schedules remove PiP transition after the animation ends. */
-    public void removePipAfterAnimation() {
-        SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
-        PipAlphaAnimator animator = mPipAlphaAnimatorSupplier.get(mContext,
-                mPipTransitionState.getPinnedTaskLeash(), tx, PipAlphaAnimator.FADE_OUT);
-        animator.setAnimationEndCallback(this::scheduleRemovePipImmediately);
-        animator.start();
+            }
+        });
     }
 
     /** Schedules remove PiP transition. */
-    private void scheduleRemovePipImmediately() {
-        WindowContainerTransaction wct = getRemovePipTransaction();
-        if (wct != null) {
-            mMainExecutor.execute(() -> {
+    public void scheduleRemovePip() {
+        mMainExecutor.execute(() -> {
+            if (!mPipTransitionState.isInPip()) return;
+            WindowContainerTransaction wct = getRemovePipTransaction();
+            if (wct != null) {
                 mPipTransitionController.startExitTransition(TRANSIT_REMOVE_PIP, wct,
                         null /* destinationBounds */);
-            });
-        }
+            }
+        });
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index acb5622b..2e38449 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -278,7 +278,8 @@
         }
 
         if (isRemovePipTransition(info)) {
-            return removePipImmediately(info, startTransaction, finishTransaction, finishCallback);
+            mPipTransitionState.setState(PipTransitionState.EXITING_PIP);
+            return startRemoveAnimation(info, startTransaction, finishTransaction, finishCallback);
         }
         return false;
     }
@@ -668,13 +669,18 @@
         return true;
     }
 
-    private boolean removePipImmediately(@NonNull TransitionInfo info,
+    private boolean startRemoveAnimation(@NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback) {
-        startTransaction.apply();
-        finishCallback.onTransitionFinished(null);
-        mPipTransitionState.setState(PipTransitionState.EXITED_PIP);
+        TransitionInfo.Change pipChange = getChangeByToken(info,
+                mPipTransitionState.getPipTaskToken());
+        mFinishCallback = finishCallback;
+        PipAlphaAnimator animator = new PipAlphaAnimator(mContext, pipChange.getLeash(),
+                startTransaction, PipAlphaAnimator.FADE_OUT);
+        finishTransaction.setAlpha(pipChange.getLeash(), 0f);
+        animator.setAnimationEndCallback(this::finishTransition);
+        animator.start();
         return true;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 246760e..535112f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -746,6 +746,7 @@
             ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "Reordering hide-task to bottom");
             wct.reorder(hideTaskToken, false /* onTop */);
         }
+        prepareTasksForSplitScreen(new int[] {taskId}, wct);
         wct.startTask(taskId, options);
         // If this should be mixed, send the task to avoid split handle transition directly.
         if (mMixedHandler != null && mMixedHandler.isTaskInPip(taskId, mTaskOrganizer)) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewRepository.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewRepository.java
new file mode 100644
index 0000000..8cb39a0
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewRepository.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.taskview;
+
+import android.annotation.Nullable;
+import android.graphics.Rect;
+import android.window.WindowContainerToken;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+/**
+ * Keeps track of all TaskViews known by Shell. This is separated into its own object so that
+ * different TaskView managers can share state.
+ */
+public class TaskViewRepository {
+    /**
+     * The latest visibility and bounds state that has been requested for
+     * a {@link TaskViewTaskController}.
+     */
+    public static class TaskViewState {
+        final WeakReference<TaskViewTaskController> mTaskView;
+        public boolean mVisible;
+        public Rect mBounds = new Rect();
+
+        TaskViewState(TaskViewTaskController taskView) {
+            mTaskView = new WeakReference<>(taskView);
+        }
+
+        @Nullable public TaskViewTaskController getTaskView() {
+            return mTaskView.get();
+        }
+    }
+
+    /**
+     * List of tracked TaskViews
+     */
+    private final ArrayList<TaskViewState> mTaskViews = new ArrayList<>();
+
+    private int findAndPrune(TaskViewTaskController tv) {
+        for (int i = mTaskViews.size() - 1; i >= 0; --i) {
+            final TaskViewTaskController key = mTaskViews.get(i).mTaskView.get();
+            if (key == null) {
+                mTaskViews.remove(i);
+                continue;
+            }
+            if (key != tv) continue;
+            return i;
+        }
+        return -1;
+    }
+
+    /** @return if the repository is tracking {@param tv}. */
+    public boolean contains(TaskViewTaskController tv) {
+        return findAndPrune(tv) >= 0;
+    }
+
+    /** Start tracking {@param tv}. */
+    public void add(TaskViewTaskController tv) {
+        if (contains(tv)) return;
+        mTaskViews.add(new TaskViewState(tv));
+    }
+
+    /** Remove {@param tv} from tracking. */
+    public void remove(TaskViewTaskController tv) {
+        int idx = findAndPrune(tv);
+        if (idx < 0) return;
+        mTaskViews.remove(idx);
+    }
+
+    /** @return whether there are any TaskViews */
+    public boolean isEmpty() {
+        if (mTaskViews.isEmpty()) return true;
+        for (int i = mTaskViews.size() - 1; i >= 0; --i) {
+            if (mTaskViews.get(i).mTaskView.get() != null) continue;
+            mTaskViews.remove(i);
+        }
+        return mTaskViews.isEmpty();
+    }
+
+    /** @return the state of {@param tv} if tracked, {@code null} otherwise. */
+    @Nullable
+    public TaskViewState byTaskView(TaskViewTaskController tv) {
+        int idx = findAndPrune(tv);
+        if (idx < 0) return null;
+        return mTaskViews.get(idx);
+    }
+
+    /**
+     * @return the state of the taskview containing {@param token} if tracked,
+     *         {@code null} otherwise.
+     */
+    @Nullable
+    public TaskViewState byToken(WindowContainerToken token) {
+        for (int i = mTaskViews.size() - 1; i >= 0; --i) {
+            final TaskViewTaskController key = mTaskViews.get(i).mTaskView.get();
+            if (key == null) {
+                mTaskViews.remove(i);
+                continue;
+            }
+            if (key.getTaskInfo() == null) continue;
+            if (key.getTaskInfo().token.equals(token)) {
+                return mTaskViews.get(i);
+            }
+        }
+        return null;
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
index eaeedba..8dd1498 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
@@ -40,6 +40,7 @@
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.wm.shell.Flags;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.SyncTransactionQueue;
@@ -619,6 +620,11 @@
         return mTaskInfo;
     }
 
+    @VisibleForTesting
+    ActivityManager.RunningTaskInfo getPendingInfo() {
+        return mPendingInfo;
+    }
+
     /**
      * Indicates that the task was not found in the start animation for the transition.
      * In this case we should clean up the task if we have the pending info. If we don't
@@ -681,6 +687,10 @@
                 wct);
     }
 
+    private TaskViewRepository.TaskViewState getState() {
+        return mTaskViewTransitions.getRepository().byTaskView(this);
+    }
+
     private void prepareOpenAnimationInternal(final boolean newTask,
             SurfaceControl.Transaction startTransaction,
             SurfaceControl.Transaction finishTransaction,
@@ -703,8 +713,16 @@
                         // TODO: maybe once b/280900002 is fixed this will be unnecessary
                         .setWindowCrop(mTaskLeash, boundsOnScreen.width(), boundsOnScreen.height());
             }
-            mTaskViewTransitions.updateBoundsState(this, boundsOnScreen);
-            mTaskViewTransitions.updateVisibilityState(this, true /* visible */);
+            if (TaskViewTransitions.useRepo()) {
+                final TaskViewRepository.TaskViewState state = getState();
+                if (state != null) {
+                    state.mBounds.set(boundsOnScreen);
+                    state.mVisible = true;
+                }
+            } else {
+                mTaskViewTransitions.updateBoundsState(this, boundsOnScreen);
+                mTaskViewTransitions.updateVisibilityState(this, true /* visible */);
+            }
             wct.setBounds(mTaskToken, boundsOnScreen);
             applyCaptionInsetsIfNeeded();
         } else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
index ae75cb5..0cbb7bd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
@@ -60,7 +60,8 @@
      * Only keep a weak reference to the controller instance here to allow for it to be cleaned
      * up when its TaskView is no longer used.
      */
-    private final Map<TaskViewTaskController, TaskViewRequestedState> mTaskViews;
+    private final Map<TaskViewTaskController, TaskViewRepository.TaskViewState> mTaskViews;
+    private final TaskViewRepository mTaskViewRepo;
     private final ArrayList<PendingTransition> mPending = new ArrayList<>();
     private final Transitions mTransitions;
     private final boolean[] mRegistered = new boolean[]{false};
@@ -95,26 +96,29 @@
         }
     }
 
-    /**
-     * Visibility and bounds state that has been requested for a {@link TaskViewTaskController}.
-     */
-    private static class TaskViewRequestedState {
-        boolean mVisible;
-        Rect mBounds = new Rect();
-    }
-
-    public TaskViewTransitions(Transitions transitions) {
+    public TaskViewTransitions(Transitions transitions, TaskViewRepository repository) {
         mTransitions = transitions;
-        if (Flags.enableTaskViewControllerCleanup()) {
+        if (useRepo()) {
+            mTaskViews = null;
+        } else if (Flags.enableTaskViewControllerCleanup()) {
             mTaskViews = new WeakHashMap<>();
         } else {
             mTaskViews = new ArrayMap<>();
         }
+        mTaskViewRepo = repository;
         // Defer registration until the first TaskView because we want this to be the "first" in
         // priority when handling requests.
         // TODO(210041388): register here once we have an explicit ordering mechanism.
     }
 
+    static boolean useRepo() {
+        return Flags.taskViewRepository() || Flags.enableBubbleAnything();
+    }
+
+    public TaskViewRepository getRepository() {
+        return mTaskViewRepo;
+    }
+
     void addTaskView(TaskViewTaskController tv) {
         synchronized (mRegistered) {
             if (!mRegistered[0]) {
@@ -122,11 +126,19 @@
                 mTransitions.addHandler(this);
             }
         }
-        mTaskViews.put(tv, new TaskViewRequestedState());
+        if (useRepo()) {
+            mTaskViewRepo.add(tv);
+        } else {
+            mTaskViews.put(tv, new TaskViewRepository.TaskViewState(null));
+        }
     }
 
     void removeTaskView(TaskViewTaskController tv) {
-        mTaskViews.remove(tv);
+        if (useRepo()) {
+            mTaskViewRepo.remove(tv);
+        } else {
+            mTaskViews.remove(tv);
+        }
         // Note: Don't unregister handler since this is a singleton with lifetime bound to Shell
     }
 
@@ -223,6 +235,10 @@
     }
 
     private TaskViewTaskController findTaskView(ActivityManager.RunningTaskInfo taskInfo) {
+        if (useRepo()) {
+            final TaskViewRepository.TaskViewState state = mTaskViewRepo.byToken(taskInfo.token);
+            return state != null ? state.getTaskView() : null;
+        }
         if (Flags.enableTaskViewControllerCleanup()) {
             for (TaskViewTaskController controller : mTaskViews.keySet()) {
                 if (controller.getTaskInfo() == null) continue;
@@ -231,8 +247,8 @@
                 }
             }
         } else {
-            ArrayMap<TaskViewTaskController, TaskViewRequestedState> taskViews =
-                    (ArrayMap<TaskViewTaskController, TaskViewRequestedState>) mTaskViews;
+            ArrayMap<TaskViewTaskController, TaskViewRepository.TaskViewState> taskViews =
+                    (ArrayMap<TaskViewTaskController, TaskViewRepository.TaskViewState>) mTaskViews;
             for (int i = 0; i < taskViews.size(); ++i) {
                 if (taskViews.keyAt(i).getTaskInfo() == null) continue;
                 if (taskInfo.token.equals(taskViews.keyAt(i).getTaskInfo().token)) {
@@ -279,23 +295,26 @@
      *
      * @param taskView the task view which the visibility is being changed for
      * @param visible  the new visibility of the task view
-     * @param reorder  whether to reorder the task or not. If this is {@code true}, the task will be
-     *                 reordered as per the given {@code visible}. For {@code visible = true}, task
-     *                 will be reordered to top. For {@code visible = false}, task will be reordered
-     *                 to the bottom
+     * @param reorder  whether to reorder the task or not. If this is {@code true}, the task will
+     *                 be reordered as per the given {@code visible}. For {@code visible = true},
+     *                 task will be reordered to top. For {@code visible = false}, task will be
+     *                 reordered to the bottom
      */
     public void setTaskViewVisible(TaskViewTaskController taskView, boolean visible,
             boolean reorder) {
-        if (mTaskViews.get(taskView) == null) return;
-        if (mTaskViews.get(taskView).mVisible == visible) return;
+        final TaskViewRepository.TaskViewState state = useRepo()
+                ? mTaskViewRepo.byTaskView(taskView)
+                : mTaskViews.get(taskView);
+        if (state == null) return;
+        if (state.mVisible == visible) return;
         if (taskView.getTaskInfo() == null) {
             // Nothing to update, task is not yet available
             return;
         }
-        mTaskViews.get(taskView).mVisible = visible;
+        state.mVisible = visible;
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         wct.setHidden(taskView.getTaskInfo().token, !visible /* hidden */);
-        wct.setBounds(taskView.getTaskInfo().token, mTaskViews.get(taskView).mBounds);
+        wct.setBounds(taskView.getTaskInfo().token, state.mBounds);
         if (reorder) {
             wct.reorder(taskView.getTaskInfo().token, visible /* onTop */);
         }
@@ -308,7 +327,10 @@
 
     /** Starts a new transition to reorder the given {@code taskView}'s task. */
     public void reorderTaskViewTask(TaskViewTaskController taskView, boolean onTop) {
-        if (mTaskViews.get(taskView) == null) return;
+        final TaskViewRepository.TaskViewState state = useRepo()
+                ? mTaskViewRepo.byTaskView(taskView)
+                : mTaskViews.get(taskView);
+        if (state == null) return;
         if (taskView.getTaskInfo() == null) {
             // Nothing to update, task is not yet available
             return;
@@ -323,19 +345,24 @@
     }
 
     void updateBoundsState(TaskViewTaskController taskView, Rect boundsOnScreen) {
-        TaskViewRequestedState state = mTaskViews.get(taskView);
+        if (useRepo()) return;
+        final TaskViewRepository.TaskViewState state = mTaskViews.get(taskView);
         if (state == null) return;
         state.mBounds.set(boundsOnScreen);
     }
 
     void updateVisibilityState(TaskViewTaskController taskView, boolean visible) {
-        TaskViewRequestedState state = mTaskViews.get(taskView);
+        final TaskViewRepository.TaskViewState state = useRepo()
+                ? mTaskViewRepo.byTaskView(taskView)
+                : mTaskViews.get(taskView);
         if (state == null) return;
         state.mVisible = visible;
     }
 
     void setTaskBounds(TaskViewTaskController taskView, Rect boundsOnScreen) {
-        TaskViewRequestedState state = mTaskViews.get(taskView);
+        final TaskViewRepository.TaskViewState state = useRepo()
+                ? mTaskViewRepo.byTaskView(taskView)
+                : mTaskViews.get(taskView);
         if (state == null || Objects.equals(boundsOnScreen, state.mBounds)) {
             return;
         }
@@ -385,7 +412,7 @@
         if (pending != null) {
             mPending.remove(pending);
         }
-        if (mTaskViews.isEmpty()) {
+        if (useRepo() ? mTaskViewRepo.isEmpty() : mTaskViews.isEmpty()) {
             if (pending != null) {
                 Slog.e(TAG, "Pending taskview transition but no task-views");
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index e80016d..1689bb5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -329,7 +329,7 @@
 
         @ColorInt int backgroundColorForTransition = 0;
         final int wallpaperTransit = getWallpaperTransitType(info);
-        boolean isDisplayRotationAnimationStarted = false;
+        int animatingDisplayId = Integer.MIN_VALUE;
         final boolean isDreamTransition = isDreamTransition(info);
         final boolean isOnlyTranslucent = isOnlyTranslucent(info);
         final boolean isActivityLevel = isActivityLevelOnly(info);
@@ -361,7 +361,7 @@
                                 ? ScreenRotationAnimation.FLAG_HAS_WALLPAPER : 0;
                         startRotationAnimation(startTransaction, change, info, anim, flags,
                                 animations, onAnimFinish);
-                        isDisplayRotationAnimationStarted = true;
+                        animatingDisplayId = change.getEndDisplayId();
                         continue;
                     }
                 } else {
@@ -426,8 +426,11 @@
 
             // Hide the invisible surface directly without animating it if there is a display
             // rotation animation playing.
-            if (isDisplayRotationAnimationStarted && TransitionUtil.isClosingType(mode)) {
-                startTransaction.hide(change.getLeash());
+            if (animatingDisplayId == change.getEndDisplayId()) {
+                if (TransitionUtil.isClosingType(mode)) {
+                    startTransaction.hide(change.getLeash());
+                }
+                // Only need to play display level animation.
                 continue;
             }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index df81821..edb2e1c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -546,8 +546,13 @@
                 // When the window is moved to front, make sure the crop is updated to prevent it
                 // from using the old crop.
                 t.setPosition(leash, change.getEndRelOffset().x, change.getEndRelOffset().y);
-                t.setWindowCrop(leash, change.getEndAbsBounds().width(),
-                        change.getEndAbsBounds().height());
+                if (change.getContainer() != null) {
+                    // We don't want to crop on non-remotable (activity), because it can have
+                    // letterbox child surface that is position at a negative position related to
+                    // the activity's surface.
+                    t.setWindowCrop(leash, change.getEndAbsBounds().width(),
+                            change.getEndAbsBounds().height());
+                }
             }
 
             // Don't move anything that isn't independent within its parents
@@ -557,8 +562,13 @@
                     t.setMatrix(leash, 1, 0, 0, 1);
                     t.setAlpha(leash, 1.f);
                     t.setPosition(leash, change.getEndRelOffset().x, change.getEndRelOffset().y);
-                    t.setWindowCrop(leash, change.getEndAbsBounds().width(),
-                            change.getEndAbsBounds().height());
+                    if (change.getContainer() != null) {
+                        // We don't want to crop on non-remotable (activity), because it can have
+                        // letterbox child surface that is position at a negative position related
+                        // to the activity's surface.
+                        t.setWindowCrop(leash, change.getEndAbsBounds().width(),
+                                change.getEndAbsBounds().height());
+                    }
                 }
                 continue;
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index a7a5f09..046cb20 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -776,6 +776,18 @@
                 DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_SPLIT_SCREEN);
     }
 
+    private void onToFloat(int taskId) {
+        final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
+        if (decoration == null) {
+            return;
+        }
+        decoration.closeHandleMenu();
+        // When the app enters float, the handle will no longer be visible, meaning
+        // we shouldn't receive input for it any longer.
+        decoration.disposeStatusBarInputLayer();
+        mDesktopTasksController.requestFloat(decoration.mTaskInfo);
+    }
+
     private void onNewWindow(int taskId) {
         final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
         if (decoration == null) {
@@ -1731,6 +1743,10 @@
             onToSplitScreen(taskInfo.taskId);
             return Unit.INSTANCE;
         });
+        windowDecoration.setOnToFloatClickListener(() -> {
+            onToFloat(taskInfo.taskId);
+            return Unit.INSTANCE;
+        });
         windowDecoration.setOpenInBrowserClickListener((intent) -> {
             onOpenInBrowser(taskInfo.taskId, intent);
         });
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 0d1960a..4ac8954 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -155,6 +155,7 @@
     private Consumer<DesktopModeTransitionSource> mOnToDesktopClickListener;
     private Function0<Unit> mOnToFullscreenClickListener;
     private Function0<Unit> mOnToSplitscreenClickListener;
+    private Function0<Unit> mOnToFloatClickListener;
     private Function0<Unit> mOnNewWindowClickListener;
     private Function0<Unit> mOnManageWindowsClickListener;
     private Function0<Unit> mOnChangeAspectRatioClickListener;
@@ -351,6 +352,11 @@
         mOnToSplitscreenClickListener = listener;
     }
 
+    /** Registers a listener to be called when the decoration's to-split action is triggered. */
+    void setOnToFloatClickListener(Function0<Unit> listener) {
+        mOnToFloatClickListener = listener;
+    }
+
     /**
      * Adds a drag resize observer that gets notified on the task being drag resized.
      *
@@ -1372,6 +1378,7 @@
                 },
                 /* onToFullscreenClickListener= */ mOnToFullscreenClickListener,
                 /* onToSplitScreenClickListener= */ mOnToSplitscreenClickListener,
+                /* onToFloatClickListener= */ mOnToFloatClickListener,
                 /* onNewWindowClickListener= */ mOnNewWindowClickListener,
                 /* onManageWindowsClickListener= */ mOnManageWindowsClickListener,
                 /* onAspectRatioSettingsClickListener= */ mOnChangeAspectRatioClickListener,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
index bb19a2c..9d73950 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
@@ -144,6 +144,7 @@
         onToDesktopClickListener: () -> Unit,
         onToFullscreenClickListener: () -> Unit,
         onToSplitScreenClickListener: () -> Unit,
+        onToFloatClickListener: () -> Unit,
         onNewWindowClickListener: () -> Unit,
         onManageWindowsClickListener: () -> Unit,
         onChangeAspectRatioClickListener: () -> Unit,
@@ -162,6 +163,7 @@
             onToDesktopClickListener = onToDesktopClickListener,
             onToFullscreenClickListener = onToFullscreenClickListener,
             onToSplitScreenClickListener = onToSplitScreenClickListener,
+            onToFloatClickListener = onToFloatClickListener,
             onNewWindowClickListener = onNewWindowClickListener,
             onManageWindowsClickListener = onManageWindowsClickListener,
             onChangeAspectRatioClickListener = onChangeAspectRatioClickListener,
@@ -183,6 +185,7 @@
         onToDesktopClickListener: () -> Unit,
         onToFullscreenClickListener: () -> Unit,
         onToSplitScreenClickListener: () -> Unit,
+        onToFloatClickListener: () -> Unit,
         onNewWindowClickListener: () -> Unit,
         onManageWindowsClickListener: () -> Unit,
         onChangeAspectRatioClickListener: () -> Unit,
@@ -208,6 +211,7 @@
             this.onToDesktopClickListener = onToDesktopClickListener
             this.onToFullscreenClickListener = onToFullscreenClickListener
             this.onToSplitScreenClickListener = onToSplitScreenClickListener
+            this.onToFloatClickListener = onToFloatClickListener
             this.onNewWindowClickListener = onNewWindowClickListener
             this.onManageWindowsClickListener = onManageWindowsClickListener
             this.onChangeAspectRatioClickListener = onChangeAspectRatioClickListener
@@ -502,6 +506,7 @@
         var onToDesktopClickListener: (() -> Unit)? = null
         var onToFullscreenClickListener: (() -> Unit)? = null
         var onToSplitScreenClickListener: (() -> Unit)? = null
+        var onToFloatClickListener: (() -> Unit)? = null
         var onNewWindowClickListener: (() -> Unit)? = null
         var onManageWindowsClickListener: (() -> Unit)? = null
         var onChangeAspectRatioClickListener: (() -> Unit)? = null
@@ -515,6 +520,7 @@
             splitscreenBtn.setOnClickListener { onToSplitScreenClickListener?.invoke() }
             desktopBtn.setOnClickListener { onToDesktopClickListener?.invoke() }
             openInAppOrBrowserBtn.setOnClickListener { onOpenInAppOrBrowserClickListener?.invoke() }
+            floatingBtn.setOnClickListener { onToFloatClickListener?.invoke() }
             openByDefaultBtn.setOnClickListener {
                 onOpenByDefaultClickListener?.invoke()
             }
@@ -640,8 +646,9 @@
         private fun bindWindowingPill(style: MenuStyle) {
             windowingPill.background.setTint(style.backgroundColor)
 
-            // TODO: Remove once implemented.
-            floatingBtn.visibility = View.GONE
+            if (!com.android.wm.shell.Flags.enableBubbleAnything()) {
+                floatingBtn.visibility = View.GONE
+            }
 
             fullscreenBtn.isSelected = taskInfo.isFullscreen
             fullscreenBtn.isEnabled = !taskInfo.isFullscreen
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.kt
index 96839ce..88cc94c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/ResizeVeil.kt
@@ -25,6 +25,7 @@
 import android.graphics.PointF
 import android.graphics.Rect
 import android.os.Trace
+import android.view.Choreographer
 import android.view.Display
 import android.view.LayoutInflater
 import android.view.SurfaceControl
@@ -331,6 +332,7 @@
                 .setPosition(icon, iconPosition.x, iconPosition.y)
                 .setPosition(parentSurface, newBounds.left.toFloat(), newBounds.top.toFloat())
                 .setWindowCrop(parentSurface, newBounds.width(), newBounds.height())
+                .setFrameTimeline(Choreographer.getInstance().vsyncId)
     }
 
     /**
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/EnterDesktopViaMenuOfStaticOverviewTaskTest.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/EnterDesktopViaMenuOfStaticOverviewTaskTest.kt
new file mode 100644
index 0000000..fac749b
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/functional/EnterDesktopViaMenuOfStaticOverviewTaskTest.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.functional
+
+import android.platform.test.annotations.Postsubmit
+import com.android.wm.shell.scenarios.EnterDesktopViaMenuOfStaticOverviewTask
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+/* Functional test for [EnterDesktopViaMenuOfStaticOverviewTask]. */
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+class EnterDesktopViaMenuOfStaticOverviewTaskTest : EnterDesktopViaMenuOfStaticOverviewTask()
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopViaMenuOfStaticOverviewTask.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopViaMenuOfStaticOverviewTask.kt
new file mode 100644
index 0000000..57647d6
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopViaMenuOfStaticOverviewTask.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.scenarios
+
+import android.app.Instrumentation
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.MailAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.Utils
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+@Ignore("Base Test Class")
+abstract class EnterDesktopViaMenuOfStaticOverviewTask constructor() {
+
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val device = UiDevice.getInstance(instrumentation)
+    private val mailApp = MailAppHelper(instrumentation)
+
+    @Rule
+    @JvmField
+    val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, Rotation.ROTATION_0)
+
+    @Before
+    fun setup() {
+        Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+        // Clear all tasks
+        val overview = tapl.goHome().switchToOverview()
+        if (overview.hasTasks()) {
+            overview.dismissAllTasks()
+        }
+        mailApp.open()
+        tapl.goHome().switchToOverview()
+    }
+
+    @Test
+    open fun desktopViaMenuOfStaticOverviewTask() {
+        tapl.overview.getCurrentTask().tapMenu().tapDesktopMenuItem()
+    }
+
+    @After
+    fun teardown() {
+        mailApp.exit()
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/Android.bp b/libs/WindowManager/Shell/tests/flicker/pip/Android.bp
index f40edae..6e0dcdb 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/pip/Android.bp
@@ -115,6 +115,11 @@
         "com.android.wm.shell.flicker.pip.PipPinchInTest",
         "com.android.wm.shell.flicker.pip.SetRequestedOrientationWhilePinned",
         "com.android.wm.shell.flicker.pip.ShowPipAndRotateDisplay",
+        "com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfAutoEnterPipOnGoToHomeTest",
+        "com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfEnterPipOnUserLeaveHintTest",
+        "com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfEnterPipViaAppUiButtonTest",
+        "com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfExitPipToAppViaExpandButtonTest",
+        "com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfExitPipToAppViaIntentTest",
     ],
     test_suites: ["device-tests"],
 }
@@ -266,12 +271,7 @@
     test_suites: ["device-tests"],
 }
 
-test_module_config {
-    name: "WMShellFlickerTestsPip-nonMatchParent",
-    base: "WMShellFlickerTestsPip",
-    include_filters: ["com.android.wm.shell.flicker.pip.nonmatchparent.*"],
-    test_suites: ["device-tests"],
-}
+// Not-match Parent test cases
 
 test_module_config {
     name: "WMShellFlickerTestsPip-BottomHalfExitPipToAppViaExpandButtonTest",
@@ -287,5 +287,26 @@
     test_suites: ["device-tests"],
 }
 
+test_module_config {
+    name: "WMShellFlickerTestsPip-BottomHalfAutoEnterPipOnGoToHomeTest",
+    base: "WMShellFlickerTestsPip",
+    include_filters: ["com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfAutoEnterPipOnGoToHomeTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "WMShellFlickerTestsPip-BottomHalfEnterPipOnUserLeaveHintTest",
+    base: "WMShellFlickerTestsPip",
+    include_filters: ["com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfEnterPipOnUserLeaveHintTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "WMShellFlickerTestsPip-BottomHalfEnterPipViaAppUiButtonTest",
+    base: "WMShellFlickerTestsPip",
+    include_filters: ["com.android.wm.shell.flicker.pip.nonmatchparent.BottomHalfEnterPipViaAppUiButtonTest"],
+    test_suites: ["device-tests"],
+}
+
 // End breakdowns for WMShellFlickerTestsPip module
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
index 609a284..84d53d5 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
@@ -24,20 +24,16 @@
 import android.tools.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.flicker.legacy.FlickerBuilder
 import android.tools.flicker.legacy.LegacyFlickerTest
-import android.tools.flicker.subject.exceptions.ExceptionMessageBuilder
-import android.tools.flicker.subject.exceptions.IncorrectRegionException
-import android.tools.flicker.subject.layers.LayerSubject
 import com.android.server.wm.flicker.helpers.PipAppHelper
 import com.android.wm.shell.Flags
 import com.android.wm.shell.flicker.pip.common.EnterPipTransition
+import com.android.wm.shell.flicker.pip.common.widthNotSmallerThan
 import org.junit.Assume
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.MethodSorters
 import org.junit.runners.Parameterized
-import kotlin.math.abs
-
 
 /**
  * Test entering pip from an app via auto-enter property when navigating to home.
@@ -77,22 +73,6 @@
         }
     }
 
-    override val defaultTeardown: FlickerBuilder.() -> Unit = { teardown { pipApp.exit(wmHelper) } }
-
-    private val widthNotSmallerThan: LayerSubject.(LayerSubject) -> Unit = {
-        val width = visibleRegion.region.bounds.width()
-        val otherWidth = it.visibleRegion.region.bounds.width()
-        if (width < otherWidth && abs(width - otherWidth) > EPSILON) {
-            val errorMsgBuilder =
-                ExceptionMessageBuilder()
-                    .forSubject(this)
-                    .forIncorrectRegion("width. $width smaller than $otherWidth")
-                    .setExpected(width)
-                    .setActual(otherWidth)
-            throw IncorrectRegionException(errorMsgBuilder)
-        }
-    }
-
     @Postsubmit
     @Test
     override fun pipLayerReduces() {
@@ -161,9 +141,4 @@
     override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
         super.visibleLayersShownMoreThanOneConsecutiveEntry()
     }
-
-    companion object {
-        // TODO(b/363080056): A margin of error allowed on certain layer size calculations.
-        const val EPSILON = 1
-    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
index 4399a23..38f37b4 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
@@ -88,6 +88,7 @@
         super.pipOverlayLayerAppearThenDisappear()
     }
 
+    // TODO(b/385086051): check if we can remove optional = true in the test.
     @Presubmit
     @Test
     fun pipAppWindowVisibleChanges() {
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipUtils.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipUtils.kt
new file mode 100644
index 0000000..3b98d9b
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipUtils.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.pip.common
+
+import android.tools.flicker.subject.exceptions.ExceptionMessageBuilder
+import android.tools.flicker.subject.exceptions.IncorrectRegionException
+import android.tools.flicker.subject.layers.LayerSubject
+import kotlin.math.abs
+
+// TODO(b/363080056): A margin of error allowed on certain layer size calculations.
+const val EPSILON = 1
+
+internal val widthNotSmallerThan: LayerSubject.(LayerSubject) -> Unit = {
+    val width = visibleRegion.region.bounds.width()
+    val otherWidth = it.visibleRegion.region.bounds.width()
+    if (width < otherWidth && abs(width - otherWidth) > EPSILON) {
+        val errorMsgBuilder =
+            ExceptionMessageBuilder()
+                .forSubject(this)
+                .forIncorrectRegion("width. $width smaller than $otherWidth")
+                .setExpected(width)
+                .setActual(otherWidth)
+        throw IncorrectRegionException(errorMsgBuilder)
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfAutoEnterPipOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfAutoEnterPipOnGoToHomeTest.kt
new file mode 100644
index 0000000..89f0226
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfAutoEnterPipOnGoToHomeTest.kt
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.pip.nonmatchparent
+
+import android.platform.test.annotations.Postsubmit
+import android.platform.test.annotations.Presubmit
+import android.platform.test.annotations.RequiresDevice
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.tools.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.flicker.legacy.FlickerBuilder
+import android.tools.flicker.legacy.LegacyFlickerTest
+import androidx.test.filters.FlakyTest
+import com.android.window.flags.Flags
+import com.android.wm.shell.flicker.pip.common.widthNotSmallerThan
+import org.junit.Assume
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test entering pip from an app with non-match parent layout via auto-enter property when
+ * navigating to home.
+ *
+ * To run this test: `atest WMShellFlickerTestsPip:BottomHalfAutoEnterPipOnGoToHomeTest`
+ *
+ * Actions:
+ * ```
+ *     Launch [BottomHalfPipLaunchingActivity] in full screen
+ *     Launch [BottomHalfPipActivity] with bottom half layout
+ *     Select "Auto-enter PiP" radio button
+ *     Press Home button or swipe up to go Home and put [BottomHalfPipActivity] in pip mode
+ * ```
+ *
+ * Notes:
+ * ```
+ *     1. All assertions are inherited from [EnterPipTest]
+ *     2. Part of the test setup occurs automatically via
+ *        [android.tools.flicker.legacy.runner.TransitionRunner],
+ *        including configuring navigation mode, initial orientation and ensuring no
+ *        apps are running before setup
+ * ```
+ */
+// TODO(b/380796448): re-enable tests after the support of non-match parent PIP animation for PIP2.
+@RequiresFlagsDisabled(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
+@RequiresFlagsEnabled(Flags.FLAG_BETTER_SUPPORT_NON_MATCH_PARENT_ACTIVITY)
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class BottomHalfAutoEnterPipOnGoToHomeTest(flicker: LegacyFlickerTest) :
+    BottomHalfEnterPipTransition(flicker) {
+
+    override val thisTransition: FlickerBuilder.() -> Unit = { transitions {
+        tapl.goHome()
+        pipApp.waitForPip(wmHelper)
+    } }
+
+    override val defaultEnterPip: FlickerBuilder.() -> Unit = {
+        setup {
+            pipApp.launchViaIntent(wmHelper)
+            pipApp.enableAutoEnterForPipActivity()
+        }
+    }
+
+    @FlakyTest(bugId = 289943985)
+    @Test
+    override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+    }
+
+    /* Gestural Navigation */
+
+    /**
+     * Checks that [pipApp] window's width is first decreasing then increasing.
+     *
+     * In gestural navigation mode, auto entering PiP can initially make the layer smaller before it
+     * gets larger.
+     * This tests verifies the width of the PiP layer first decreases and then increases due to
+     * size and scale animations going to different directions.
+     *
+     * Note that we still allow a margin of error of 1px, since around the time
+     * of handoff between gesture nav task view simulator and
+     * SwipePipToHomeAnimator, crop can get a bit smaller and scale can get a
+     * bit larger if swiped aggressively - this can produce off-by-1 errors for
+     * width too.
+     */
+    @Postsubmit
+    @Test
+    fun pipLayerWidthDecreasesThenIncreases() {
+        Assume.assumeTrue(flicker.scenario.isGesturalNavigation)
+        flicker.assertLayers {
+            val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
+            var previousLayer = pipLayerList[0]
+            var currentLayer = previousLayer
+            var i = 0
+            invoke("layer area is decreasing") {
+                if (i < pipLayerList.size - 1) {
+                    previousLayer = currentLayer
+                    currentLayer = pipLayerList[++i]
+                    previousLayer.widthNotSmallerThan(currentLayer)
+                }
+            }.then().invoke("layer are is increasing", true /* isOptional */) {
+                if (i < pipLayerList.size - 1) {
+                    previousLayer = currentLayer
+                    currentLayer = pipLayerList[++i]
+                    currentLayer.widthNotSmallerThan(previousLayer)
+                }
+            }
+        }
+    }
+
+    /* 3-button Navigation */
+
+    /**
+     * The PIP layer reduces continuously in 3-Button navigation mode.
+     */
+    @Postsubmit
+    @Test
+    override fun pipLayerReduces() {
+        Assume.assumeFalse(flicker.scenario.isGesturalNavigation)
+        flicker.assertLayers {
+            val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
+            pipLayerList.zipWithNext { previous, current ->
+                current.visibleRegion.notBiggerThan(previous.visibleRegion.region)
+            }
+        }
+    }
+
+    /** Checks that [pipApp] window is animated towards default position in right bottom corner */
+    @FlakyTest(bugId = 255578530)
+    @Test
+    fun pipLayerMovesTowardsRightBottomCorner() {
+        // in gestural nav the swipe makes PiP first go upwards
+        Assume.assumeFalse(flicker.scenario.isGesturalNavigation)
+        flicker.assertLayers {
+            val pipLayerList = this.layers { pipApp.layerMatchesAnyOf(it) && it.isVisible }
+            // Pip animates towards the right bottom corner, but because it is being resized at the
+            // same time, it is possible it shrinks first quickly below the default position and get
+            // moved up after that in just few last frames
+            pipLayerList.zipWithNext { previous, current ->
+                current.visibleRegion.isToTheRightBottom(previous.visibleRegion.region, 3)
+            }
+        }
+    }
+
+    @Presubmit
+    @Test
+    override fun focusChanges() {
+        // in gestural nav the focus goes to different activity on swipe up
+        Assume.assumeFalse(flicker.scenario.isGesturalNavigation)
+        super.focusChanges()
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipOnUserLeaveHintTest.kt
new file mode 100644
index 0000000..8642b6c
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipOnUserLeaveHintTest.kt
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.pip.nonmatchparent
+
+import android.platform.test.annotations.Presubmit
+import android.platform.test.annotations.RequiresDevice
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.tools.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.flicker.legacy.FlickerBuilder
+import android.tools.flicker.legacy.LegacyFlickerTest
+import com.android.window.flags.Flags
+import org.junit.Assume
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test entering pip from an app with bottom half layout via [onUserLeaveHint] and by navigating to
+ * home.
+ *
+ * To run this test: `atest WMShellFlickerTestsPip:BottomHalfEnterPipOnUserLeaveHintTest`
+ *
+ * Actions:
+ * ```
+ *     Launch [BottomHalfPipLaunchingActivity] in full screen
+ *     Launch [BottomHalfPipActivity] with bottom half layout
+ *     Select "Via code behind" radio button
+ *     Press Home button or swipe up to go Home and put [pipApp] in pip mode
+ * ```
+ * Notes:
+ * ```
+ *     1. All assertions are inherited from [EnterPipTest]
+ *     2. Part of the test setup occurs automatically via
+ *        [android.tools.flicker.legacy.runner.TransitionRunner],
+ *        including configuring navigation mode, initial orientation and ensuring no
+ *        apps are running before setup
+ * ```
+ */
+// TODO(b/380796448): re-enable tests after the support of non-match parent PIP animation for PIP2.
+@RequiresFlagsDisabled(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
+@RequiresFlagsEnabled(Flags.FLAG_BETTER_SUPPORT_NON_MATCH_PARENT_ACTIVITY)
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class BottomHalfEnterPipOnUserLeaveHintTest(flicker: LegacyFlickerTest) :
+    BottomHalfEnterPipTransition(flicker)
+{
+    override val thisTransition: FlickerBuilder.() -> Unit = { transitions {
+        tapl.goHome()
+        pipApp.waitForPip(wmHelper)
+    } }
+
+    override val defaultEnterPip: FlickerBuilder.() -> Unit = {
+        setup {
+            pipApp.launchViaIntent(wmHelper)
+            pipApp.enableEnterPipOnUserLeaveHint()
+        }
+    }
+
+    // gestural navigation
+
+    // TODO(b/385086051): check if we can remove optional = true in the test.
+    @Presubmit
+    @Test
+    fun pipAppWindowVisibleChanges() {
+        // pip layer in gesture nav will disappear during transition
+        Assume.assumeTrue(flicker.scenario.isGesturalNavigation)
+        flicker.assertWm {
+            this.isAppWindowVisible(pipApp)
+                .then()
+                .isAppWindowInvisible(pipApp, isOptional = true)
+                .then()
+                .isAppWindowVisible(pipApp, isOptional = true)
+        }
+    }
+
+    @Presubmit
+    @Test
+    fun pipAppLayerVisibleChanges() {
+        Assume.assumeTrue(flicker.scenario.isGesturalNavigation)
+        // pip layer in gesture nav will disappear during transition
+        flicker.assertLayers {
+            this.isVisible(pipApp).then().isInvisible(pipApp).then().isVisible(pipApp)
+        }
+    }
+
+    @Presubmit
+    @Test
+    fun pipLayerRemainInsideVisibleBounds() {
+        // pip layer in gesture nav will disappear during transition
+        Assume.assumeTrue(flicker.scenario.isGesturalNavigation)
+        // pip layer in gesture nav will disappear during transition
+        flicker.assertLayersStart { this.visibleRegion(pipApp).coversAtMost(displayBounds) }
+        flicker.assertLayersEnd { this.visibleRegion(pipApp).coversAtMost(displayBounds) }
+    }
+
+    // 3-button navigation
+
+    @Presubmit
+    @Test
+    override fun pipAppWindowAlwaysVisible() {
+        // In gestural nav the pip will first move behind home and then above home. The visual
+        // appearance visible->invisible->visible is asserted by pipAppLayerAlwaysVisible().
+        // But the internal states of activity don't need to follow that, such as a temporary
+        // visibility state can be changed quickly outside a transaction so the test doesn't
+        // detect that. Hence, skip the case to avoid restricting the internal implementation.
+        Assume.assumeFalse(flicker.scenario.isGesturalNavigation)
+        super.pipAppWindowAlwaysVisible()
+    }
+
+    @Presubmit
+    @Test
+    override fun pipAppLayerAlwaysVisible() {
+        // pip layer in gesture nav will disappear during transition
+        Assume.assumeFalse(flicker.scenario.isGesturalNavigation)
+        super.pipAppLayerAlwaysVisible()
+    }
+
+    @Presubmit
+    @Test
+    override fun pipOverlayLayerAppearThenDisappear() {
+        // no overlay in gesture nav for non-auto enter PiP transition
+        Assume.assumeFalse(flicker.scenario.isGesturalNavigation)
+        super.pipOverlayLayerAppearThenDisappear()
+    }
+
+    @Presubmit
+    @Test
+    override fun pipLayerReduces() {
+        // in gestural nav the pip enters through alpha animation
+        Assume.assumeFalse(flicker.scenario.isGesturalNavigation)
+        super.pipLayerReduces()
+    }
+
+    @Presubmit
+    @Test
+    override fun focusChanges() {
+        // in gestural nav the focus goes to different activity on swipe up
+        Assume.assumeFalse(flicker.scenario.isGesturalNavigation)
+        super.focusChanges()
+    }
+
+    @Presubmit
+    @Test
+    override fun pipLayerOrOverlayRemainInsideVisibleBounds() {
+        // pip layer in gesture nav will disappear during transition
+        Assume.assumeFalse(flicker.scenario.isGesturalNavigation)
+        super.pipLayerOrOverlayRemainInsideVisibleBounds()
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipTransition.kt
new file mode 100644
index 0000000..a455de9
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipTransition.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.pip.nonmatchparent
+
+import android.platform.test.annotations.Presubmit
+import android.tools.flicker.legacy.LegacyFlickerTest
+import com.android.server.wm.flicker.helpers.BottomHalfPipAppHelper
+import com.android.server.wm.flicker.helpers.PipAppHelper
+import com.android.wm.shell.flicker.pip.common.EnterPipTransition
+import org.junit.Test
+
+/**
+ * The base class to test enter PIP animation on bottom half activity.
+ */
+abstract class BottomHalfEnterPipTransition(flicker: LegacyFlickerTest) :
+    EnterPipTransition(flicker)
+{
+    override val pipApp: PipAppHelper = BottomHalfPipAppHelper(
+        instrumentation,
+        useLaunchingActivity = true
+    )
+
+    @Presubmit
+    @Test
+    override fun pipWindowRemainInsideVisibleBounds() {
+        // We only verify the start and end because we update the layout when
+        // the BottomHalfPipActivity goes to PIP mode, which may lead to intermediate state that
+        // the window frame may be out of the display frame.
+        flicker.assertWmStart { visibleRegion(pipApp).coversAtMost(displayBounds) }
+        flicker.assertLayersEnd { visibleRegion(pipApp).coversAtMost(displayBounds) }
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipViaAppUiButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipViaAppUiButtonTest.kt
new file mode 100644
index 0000000..cfdd4e5
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipViaAppUiButtonTest.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.flicker.pip.nonmatchparent
+
+import android.platform.test.annotations.Presubmit
+import android.platform.test.annotations.RequiresDevice
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.tools.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.flicker.legacy.FlickerBuilder
+import android.tools.flicker.legacy.LegacyFlickerTest
+import android.tools.traces.parsers.toFlickerComponent
+import com.android.server.wm.flicker.testapp.ActivityOptions.BottomHalfPip.LAUNCHING_APP_COMPONENT
+import com.android.window.flags.Flags
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test entering pip from an app by interacting with the app UI
+ *
+ * To run this test: `atest WMShellFlickerTestsPip:BottomHalfEnterPipViaAppUiButtonTest`
+ *
+ * Actions:
+ * ```
+ *     Launch [BottomHalfPipLaunchingActivity] in full screen
+ *     Launch [BottomHalfPipActivity] with bottom half layout
+ *     Press an "enter pip" button to put [pipApp] in pip mode
+ * ```
+ *
+ * Notes:
+ * ```
+ *     1. Some default assertions (e.g., nav bar, status bar and screen covered)
+ *        are inherited from [PipTransition]
+ *     2. Part of the test setup occurs automatically via
+ *        [android.tools.flicker.legacy.runner.TransitionRunner],
+ *        including configuring navigation mode, initial orientation and ensuring no
+ *        apps are running before setup
+ * ```
+ */
+// TODO(b/380796448): re-enable tests after the support of non-match parent PIP animation for PIP2.
+@RequiresFlagsDisabled(com.android.wm.shell.Flags.FLAG_ENABLE_PIP2)
+@RequiresFlagsEnabled(Flags.FLAG_BETTER_SUPPORT_NON_MATCH_PARENT_ACTIVITY)
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class BottomHalfEnterPipViaAppUiButtonTest(flicker: LegacyFlickerTest) :
+    BottomHalfEnterPipTransition(flicker)
+{
+    override val thisTransition: FlickerBuilder.() -> Unit = {
+        transitions { pipApp.clickEnterPipButton(wmHelper) }
+    }
+
+    /**
+     * Checks if the focus changes to the launching activity behind when the bottom half [pipApp]
+     * goes to PIP mode.
+     */
+    @Presubmit
+    @Test
+    override fun focusChanges() {
+        flicker.assertEventLog {
+            this.focusChanges(
+                pipApp.packageName,
+                LAUNCHING_APP_COMPONENT.packageName
+            )
+        }
+    }
+
+    @Presubmit
+    @Test
+    override fun launcherLayerBecomesVisible() {
+        // Disable the test since the background activity is BottomHalfPipLaunchingActivity.
+    }
+
+    /**
+     * Checks if the launching activity behind the bottom half [pipApp] is always visible during
+     * the transition.
+     */
+    @Presubmit
+    @Test
+    fun launchingAppLayerAlwaysVisible() {
+        flicker.assertLayers { isVisible(LAUNCHING_APP_COMPONENT.toFlickerComponent()) }
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt
index 1f2eaa6..eeb83df 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleViewInfoTest.kt
@@ -33,10 +33,10 @@
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.TestShellExecutor
-import com.android.wm.shell.WindowManagerShellWrapper
 import com.android.wm.shell.bubbles.bar.BubbleBarLayerView
 import com.android.wm.shell.bubbles.properties.BubbleProperties
 import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayImeController
 import com.android.wm.shell.common.DisplayInsetsController
 import com.android.wm.shell.common.FloatingContentCoordinator
 import com.android.wm.shell.common.ShellExecutor
@@ -123,7 +123,8 @@
                 mock<BubbleDataRepository>(),
                 mock<IStatusBarService>(),
                 windowManager,
-                WindowManagerShellWrapper(mainExecutor),
+                mock<DisplayInsetsController>(),
+                mock<DisplayImeController>(),
                 mock<UserManager>(),
                 mock<LauncherApps>(),
                 bubbleLogger,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index fe08526..e032616 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -93,6 +93,7 @@
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.TestRunningTaskInfoBuilder
 import com.android.wm.shell.TestShellExecutor
+import com.android.wm.shell.bubbles.BubbleController
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayLayout
 import com.android.wm.shell.common.MultiInstanceHelper
@@ -232,6 +233,7 @@
     @Mock private lateinit var mockToast: Toast
     private lateinit var mockitoSession: StaticMockitoSession
     @Mock private lateinit var desktopTilingDecorViewModel: DesktopTilingDecorViewModel
+    @Mock private lateinit var bubbleController: BubbleController
     @Mock private lateinit var desktopWindowDecoration: DesktopModeWindowDecoration
     @Mock private lateinit var resources: Resources
     @Mock
@@ -383,6 +385,7 @@
             desktopModeUiEventLogger,
             desktopTilingDecorViewModel,
             desktopWallpaperActivityTokenProvider,
+            Optional.of(bubbleController),
         )
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
index 3fe8c10..a8aa257 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java
@@ -120,15 +120,22 @@
     @Test
     public void scheduleExitPipViaExpand_nullTaskToken_noop() {
         setNullPipTaskToken();
+        when(mMockPipTransitionState.isInPip()).thenReturn(true);
 
         mPipScheduler.scheduleExitPipViaExpand();
 
-        verify(mMockMainExecutor, never()).execute(any());
+        verify(mMockMainExecutor, times(1)).execute(mRunnableArgumentCaptor.capture());
+        assertNotNull(mRunnableArgumentCaptor.getValue());
+        mRunnableArgumentCaptor.getValue().run();
+
+        verify(mMockPipTransitionController, never())
+                .startExitTransition(eq(TRANSIT_EXIT_PIP), any(), isNull());
     }
 
     @Test
     public void scheduleExitPipViaExpand_exitTransitionCalled() {
         setMockPipTaskToken();
+        when(mMockPipTransitionState.isInPip()).thenReturn(true);
 
         mPipScheduler.scheduleExitPipViaExpand();
 
@@ -142,20 +149,13 @@
 
     @Test
     public void removePipAfterAnimation() {
-        //TODO: Update once this is changed to run animation as part of transition
         setMockPipTaskToken();
+        when(mMockPipTransitionState.isInPip()).thenReturn(true);
 
-        mPipScheduler.removePipAfterAnimation();
-        verify(mMockAlphaAnimator, times(1))
-                .setAnimationEndCallback(mRunnableArgumentCaptor.capture());
-        assertNotNull(mRunnableArgumentCaptor.getValue());
-        verify(mMockAlphaAnimator, times(1)).start();
-
-        mRunnableArgumentCaptor.getValue().run();
+        mPipScheduler.scheduleRemovePip();
 
         verify(mMockMainExecutor, times(1)).execute(mRunnableArgumentCaptor.capture());
         assertNotNull(mRunnableArgumentCaptor.getValue());
-
         mRunnableArgumentCaptor.getValue().run();
 
         verify(mMockPipTransitionController, times(1))
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java
index 17fd95b..66636c5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java
@@ -20,6 +20,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
@@ -45,7 +50,8 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Looper;
-import android.testing.AndroidTestingRunner;
+import android.platform.test.flag.junit.FlagsParameterization;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.testing.TestableLooper;
 import android.view.SurfaceControl;
 import android.view.SurfaceHolder;
@@ -55,6 +61,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.wm.shell.Flags;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestHandler;
@@ -65,17 +72,33 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
 
+import java.util.List;
+
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(ParameterizedAndroidJunit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class TaskViewTest extends ShellTestCase {
 
+    @Parameters(name = "{0}")
+    public static List<FlagsParameterization> getParams() {
+        return FlagsParameterization.allCombinationsOf(Flags.FLAG_TASK_VIEW_REPOSITORY);
+    }
+
+    @Rule
+    public final SetFlagsRule mSetFlagsRule;
+
     @Mock
     TaskView.Listener mViewListener;
     @Mock
@@ -84,6 +107,8 @@
     WindowContainerToken mToken;
     @Mock
     ShellTaskOrganizer mOrganizer;
+    @Captor
+    ArgumentCaptor<WindowContainerTransaction> mWctCaptor;
     @Mock
     HandlerExecutor mExecutor;
     @Mock
@@ -98,9 +123,14 @@
 
     Context mContext;
     TaskView mTaskView;
+    TaskViewRepository mTaskViewRepository;
     TaskViewTransitions mTaskViewTransitions;
     TaskViewTaskController mTaskViewTaskController;
 
+    public TaskViewTest(FlagsParameterization flags) {
+        mSetFlagsRule = new SetFlagsRule(flags);
+    }
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -134,9 +164,10 @@
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
             doReturn(true).when(mTransitions).isRegistered();
         }
-        mTaskViewTransitions = spy(new TaskViewTransitions(mTransitions));
-        mTaskViewTaskController = spy(new TaskViewTaskController(mContext, mOrganizer,
-                mTaskViewTransitions, mSyncQueue));
+        mTaskViewRepository = new TaskViewRepository();
+        mTaskViewTransitions = spy(new TaskViewTransitions(mTransitions, mTaskViewRepository));
+        mTaskViewTaskController = new TaskViewTaskController(mContext, mOrganizer,
+                mTaskViewTransitions, mSyncQueue);
         mTaskView = new TaskView(mContext, mTaskViewTaskController);
         mTaskView.setHandler(mViewHandler);
         mTaskView.setListener(mExecutor, mViewListener);
@@ -482,8 +513,14 @@
 
         // Surface created, but task not available so bounds / visibility isn't set
         mTaskView.surfaceCreated(mock(SurfaceHolder.class));
-        verify(mTaskViewTransitions, never()).updateVisibilityState(
-                eq(mTaskViewTaskController), eq(true));
+        if (TaskViewTransitions.useRepo()) {
+            assertNotNull(mTaskViewTransitions.getRepository().byTaskView(mTaskViewTaskController));
+            assertFalse(mTaskViewTransitions.getRepository().byTaskView(mTaskViewTaskController)
+                    .mVisible);
+        } else {
+            verify(mTaskViewTransitions, never()).updateVisibilityState(
+                    eq(mTaskViewTaskController), eq(true));
+        }
 
         // Make the task available
         WindowContainerTransaction wct = mock(WindowContainerTransaction.class);
@@ -492,8 +529,16 @@
         // Bounds got set
         verify(wct).setBounds(any(WindowContainerToken.class), eq(bounds));
         // Visibility & bounds state got set
-        verify(mTaskViewTransitions).updateVisibilityState(eq(mTaskViewTaskController), eq(true));
-        verify(mTaskViewTransitions).updateBoundsState(eq(mTaskViewTaskController), eq(bounds));
+        if (TaskViewTransitions.useRepo()) {
+            assertTrue(mTaskViewTransitions.getRepository().byTaskView(mTaskViewTaskController)
+                    .mVisible);
+            assertEquals(mTaskViewTransitions.getRepository().byTaskView(mTaskViewTaskController)
+                    .mBounds, bounds);
+        } else {
+            verify(mTaskViewTransitions).updateVisibilityState(eq(mTaskViewTaskController),
+                    eq(true));
+            verify(mTaskViewTransitions).updateBoundsState(eq(mTaskViewTaskController), eq(bounds));
+        }
     }
 
     @Test
@@ -507,8 +552,15 @@
 
         // Surface created, but task not available so bounds / visibility isn't set
         mTaskView.surfaceCreated(mock(SurfaceHolder.class));
-        verify(mTaskViewTransitions, never()).updateVisibilityState(
-                eq(mTaskViewTaskController), eq(true));
+        if (TaskViewTransitions.useRepo()) {
+            assertNotNull(mTaskViewTransitions.getRepository().byTaskView(
+                    mTaskViewTaskController));
+            assertFalse(mTaskViewTransitions.getRepository().byTaskView(mTaskViewTaskController)
+                    .mVisible);
+        } else {
+            verify(mTaskViewTransitions, never()).updateVisibilityState(
+                    eq(mTaskViewTaskController), eq(true));
+        }
 
         // Make the task available / start prepareOpen
         WindowContainerTransaction wct = mock(WindowContainerTransaction.class);
@@ -519,8 +571,16 @@
         // Bounds got set
         verify(wct).setBounds(any(WindowContainerToken.class), eq(bounds));
         // Visibility & bounds state got set
-        verify(mTaskViewTransitions).updateVisibilityState(eq(mTaskViewTaskController), eq(true));
-        verify(mTaskViewTransitions).updateBoundsState(eq(mTaskViewTaskController), eq(bounds));
+        if (TaskViewTransitions.useRepo()) {
+            assertTrue(mTaskViewTransitions.getRepository().byTaskView(mTaskViewTaskController)
+                    .mVisible);
+            assertEquals(mTaskViewTransitions.getRepository().byTaskView(mTaskViewTaskController)
+                    .mBounds, bounds);
+        } else {
+            verify(mTaskViewTransitions).updateVisibilityState(eq(mTaskViewTaskController),
+                    eq(true));
+            verify(mTaskViewTransitions).updateBoundsState(eq(mTaskViewTaskController), eq(bounds));
+        }
     }
 
     @Test
@@ -541,8 +601,17 @@
         // Bounds do not get set as there is no surface
         verify(wct, never()).setBounds(any(WindowContainerToken.class), any());
         // Visibility is set to false, bounds aren't set
-        verify(mTaskViewTransitions).updateVisibilityState(eq(mTaskViewTaskController), eq(false));
-        verify(mTaskViewTransitions, never()).updateBoundsState(eq(mTaskViewTaskController), any());
+        if (TaskViewTransitions.useRepo()) {
+            assertFalse(mTaskViewTransitions.getRepository().byTaskView(mTaskViewTaskController)
+                    .mVisible);
+            assertTrue(mTaskViewTransitions.getRepository().byTaskView(mTaskViewTaskController)
+                    .mBounds.isEmpty());
+        } else {
+            verify(mTaskViewTransitions).updateVisibilityState(eq(mTaskViewTaskController),
+                    eq(false));
+            verify(mTaskViewTransitions, never()).updateBoundsState(eq(mTaskViewTaskController),
+                    any());
+        }
     }
 
     @Test
@@ -576,7 +645,7 @@
         mTaskViewTaskController.setTaskNotFound();
         mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash);
 
-        verify(mTaskViewTaskController).cleanUpPendingTask();
+        assertNull(mTaskViewTaskController.getTaskInfo());
         verify(mTaskViewTransitions).closeTaskView(any(), eq(mTaskViewTaskController));
     }
 
@@ -585,7 +654,8 @@
         assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS);
 
         mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash);
-        verify(mTaskViewTaskController, never()).cleanUpPendingTask();
+        assertEquals(mTaskInfo, mTaskViewTaskController.getPendingInfo());
+        verify(mTaskViewTransitions, never()).closeTaskView(any(), any());
     }
 
     @Test
@@ -596,20 +666,20 @@
         mTaskView.setCaptionInsets(Insets.of(insets));
         mTaskView.onComputeInternalInsets(new ViewTreeObserver.InternalInsetsInfo());
 
-        verify(mTaskViewTaskController).applyCaptionInsetsIfNeeded();
         verify(mOrganizer, never()).applyTransaction(any());
 
         mTaskView.surfaceCreated(mock(SurfaceHolder.class));
         reset(mOrganizer);
-        reset(mTaskViewTaskController);
         WindowContainerTransaction wct = new WindowContainerTransaction();
         mTaskViewTaskController.prepareOpenAnimation(true /* newTask */,
                 new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo,
                 mLeash, wct);
         mTaskView.onComputeInternalInsets(new ViewTreeObserver.InternalInsetsInfo());
 
-        verify(mTaskViewTaskController).applyCaptionInsetsIfNeeded();
-        verify(mOrganizer).applyTransaction(any());
+        verify(mOrganizer).applyTransaction(mWctCaptor.capture());
+        assertTrue(mWctCaptor.getValue().getHierarchyOps().stream().anyMatch(hop ->
+                hop.getType() == WindowContainerTransaction.HierarchyOp
+                        .HIERARCHY_OP_TYPE_ADD_INSETS_FRAME_PROVIDER));
     }
 
     @Test
@@ -621,14 +691,15 @@
         mTaskViewTaskController.prepareOpenAnimation(true /* newTask */,
                 new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo,
                 mLeash, wct);
-        reset(mTaskViewTaskController);
         reset(mOrganizer);
 
         Rect insets = new Rect(0, 400, 0, 0);
         mTaskView.setCaptionInsets(Insets.of(insets));
         mTaskView.onComputeInternalInsets(new ViewTreeObserver.InternalInsetsInfo());
-        verify(mTaskViewTaskController).applyCaptionInsetsIfNeeded();
-        verify(mOrganizer).applyTransaction(any());
+        verify(mOrganizer).applyTransaction(mWctCaptor.capture());
+        assertTrue(mWctCaptor.getValue().getHierarchyOps().stream().anyMatch(hop ->
+                hop.getType() == WindowContainerTransaction.HierarchyOp
+                        .HIERARCHY_OP_TYPE_ADD_INSETS_FRAME_PROVIDER));
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java
index 60e2030..5f6f18f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java
@@ -83,6 +83,7 @@
     @Mock
     WindowContainerToken mToken;
 
+    TaskViewRepository mTaskViewRepository;
     TaskViewTransitions mTaskViewTransitions;
 
     public TaskViewTransitionsTest(FlagsParameterization flags) {
@@ -102,7 +103,8 @@
         mTaskInfo.taskId = 314;
         mTaskInfo.taskDescription = mock(ActivityManager.TaskDescription.class);
 
-        mTaskViewTransitions = spy(new TaskViewTransitions(mTransitions));
+        mTaskViewRepository = new TaskViewRepository();
+        mTaskViewTransitions = spy(new TaskViewTransitions(mTransitions, mTaskViewRepository));
         mTaskViewTransitions.addTaskView(mTaskViewTaskController);
         when(mTaskViewTaskController.getTaskInfo()).thenReturn(mTaskInfo);
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index e99e5cc..7dac085 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -1091,6 +1091,7 @@
                 any(),
                 any(),
                 any(),
+                any(),
                 openInBrowserCaptor.capture(),
                 any(),
                 any(),
@@ -1127,6 +1128,7 @@
                 any(),
                 any(),
                 any(),
+                any(),
                 openInBrowserCaptor.capture(),
                 any(),
                 any(),
@@ -1158,6 +1160,7 @@
                 any(),
                 any(),
                 any(),
+                any(),
                 openInBrowserCaptor.capture(),
                 any(),
                 any(),
@@ -1226,6 +1229,7 @@
                 any(),
                 any(),
                 any(),
+                any(),
                 closeClickListener.capture(),
                 any(),
                 anyBoolean()
@@ -1258,6 +1262,7 @@
                 any(),
                 any(),
                 any(),
+                any(),
                 /* forceShowSystemBars= */ eq(true)
         );
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
index cbfb57e..f90988e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
@@ -307,6 +307,7 @@
             onToDesktopClickListener = mock(),
             onToFullscreenClickListener = mock(),
             onToSplitScreenClickListener = mock(),
+            onToFloatClickListener = mock(),
             onNewWindowClickListener = mock(),
             onManageWindowsClickListener = mock(),
             onChangeAspectRatioClickListener = mock(),
diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java
index f7f10df..4f7132a 100644
--- a/media/java/android/media/projection/MediaProjection.java
+++ b/media/java/android/media/projection/MediaProjection.java
@@ -324,6 +324,19 @@
     }
 
     /**
+     * Stops projection.
+     * @hide
+     */
+    public void stop(@StopReason int stopReason) {
+        try {
+            Log.d(TAG, "Content Recording: stopping projection");
+            mImpl.stop(stopReason);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to stop projection", e);
+        }
+    }
+
+    /**
      * Get the underlying IMediaProjection.
      * @hide
      */
diff --git a/media/java/android/media/quality/MediaQualityManager.java b/media/java/android/media/quality/MediaQualityManager.java
index 7e87462..166b388 100644
--- a/media/java/android/media/quality/MediaQualityManager.java
+++ b/media/java/android/media/quality/MediaQualityManager.java
@@ -276,16 +276,19 @@
     /**
      * Sets preferred default picture profile.
      *
-     * @param id the ID of the default profile. {@code null} to unset the default profile.
+     * @param pictureProfileId the ID of the default profile. {@code null} to unset the default
+     *                         profile.
      * @return {@code true} if it's set successfully; {@code false} otherwise.
      *
+     * @see PictureProfile#getProfileId()
+     *
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE)
-    public boolean setDefaultPictureProfile(@Nullable String id) {
+    public boolean setDefaultPictureProfile(@Nullable String pictureProfileId) {
         try {
-            return mService.setDefaultPictureProfile(id, mUserHandle);
+            return mService.setDefaultPictureProfile(pictureProfileId, mUserHandle);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -467,16 +470,19 @@
     /**
      * Sets preferred default sound profile.
      *
-     * @param id the ID of the default profile. {@code null} to unset the default profile.
+     * @param soundProfileId the ID of the default profile. {@code null} to unset the default
+     *                       profile.
      * @return {@code true} if it's set successfully; {@code false} otherwise.
      *
+     * @see SoundProfile#getProfileId()
+     *
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE)
-    public boolean setDefaultSoundProfile(@Nullable String id) {
+    public boolean setDefaultSoundProfile(@Nullable String soundProfileId) {
         try {
-            return mService.setDefaultSoundProfile(id, mUserHandle);
+            return mService.setDefaultSoundProfile(soundProfileId, mUserHandle);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/native/android/OWNERS b/native/android/OWNERS
index 1fde7d2..3ea2d35 100644
--- a/native/android/OWNERS
+++ b/native/android/OWNERS
@@ -29,6 +29,7 @@
 # Input
 per-file input.cpp = file:/INPUT_OWNERS
 
-# PerformanceHint
+# ADPF
 per-file performance_hint.cpp = file:/ADPF_OWNERS
+per-file system_health.cpp = file:/ADPF_OWNERS
 per-file thermal.cpp = file:/ADPF_OWNERS
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 1ccadf9..f629c88 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -396,6 +396,7 @@
     APerformanceHint_notifyWorkloadSpike; # introduced=36
     APerformanceHint_borrowSessionFromJava; # introduced=36
     APerformanceHint_setNativeSurfaces; # introduced=36
+    APerformanceHint_isFeatureSupported; # introduced=36
     AWorkDuration_create; # introduced=VanillaIceCream
     AWorkDuration_release; # introduced=VanillaIceCream
     AWorkDuration_setWorkPeriodStartTimestampNanos; # introduced=VanillaIceCream
@@ -419,7 +420,6 @@
     AThermal_setIThermalServiceForTesting;
     APerformanceHint_setIHintManagerForTesting;
     APerformanceHint_sendHint;
-    APerformanceHint_setUseGraphicsPipelineForTesting;
     APerformanceHint_getThreadIds;
     APerformanceHint_createSessionInternal;
     APerformanceHint_createSessionUsingConfigInternal;
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 9257901..7e65523 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -71,26 +71,31 @@
 
 struct APerformanceHintSession;
 
-constexpr int64_t SEND_HINT_TIMEOUT = std::chrono::nanoseconds(100ms).count();
 struct AWorkDuration : public hal::WorkDuration {};
 struct ASessionCreationConfig : public SessionCreationConfig {
     std::vector<wp<IBinder>> layers{};
-    bool hasMode(hal::SessionMode&& mode) {
+    bool hasMode(hal::SessionMode mode) {
         return std::find(modesToEnable.begin(), modesToEnable.end(), mode) != modesToEnable.end();
     }
+    void setMode(hal::SessionMode mode, bool enabled) {
+        if (hasMode(mode)) {
+            if (!enabled) {
+                std::erase(modesToEnable, mode);
+            }
+        } else if (enabled) {
+            modesToEnable.push_back(mode);
+        }
+    }
 };
 
-bool kForceGraphicsPipeline = false;
-
-bool useGraphicsPipeline() {
-    return android::os::adpf_graphics_pipeline() || kForceGraphicsPipeline;
-}
-
 // A pair of values that determine the behavior of the
 // load hint rate limiter, to only allow "X hints every Y seconds"
-constexpr double kLoadHintInterval = std::chrono::nanoseconds(2s).count();
+constexpr int64_t kLoadHintInterval = std::chrono::nanoseconds(2s).count();
 constexpr double kMaxLoadHintsPerInterval = 20;
-constexpr double kReplenishRate = kMaxLoadHintsPerInterval / kLoadHintInterval;
+// Replenish rate is used for new rate limiting behavior, it currently replenishes at a rate of
+// 20 / 2s = 1 per 100us, which is the same limit as before, just enforced differently
+constexpr double kReplenishRate = kMaxLoadHintsPerInterval / static_cast<double>(kLoadHintInterval);
+constexpr int64_t kSendHintTimeout = kLoadHintInterval / kMaxLoadHintsPerInterval;
 bool kForceNewHintBehavior = false;
 
 template <class T>
@@ -149,9 +154,7 @@
     std::future<bool> mChannelCreationFinished;
 };
 
-class SupportInfoWrapper {
-public:
-    SupportInfoWrapper(hal::SupportInfo& info);
+struct SupportInfoWrapper : public hal::SupportInfo {
     bool isSessionModeSupported(hal::SessionMode mode);
     bool isSessionHintSupported(hal::SessionHint hint);
 
@@ -162,7 +165,6 @@
         // over that much and cutting off any extra values
         return (supportBitfield >> static_cast<int>(enumValue)) % 2;
     }
-    hal::SupportInfo mSupportInfo;
 };
 
 class HintManagerClient : public IHintManager::BnHintManagerClient {
@@ -188,9 +190,9 @@
                                            bool isJava = false);
     APerformanceHintSession* getSessionFromJava(JNIEnv* _Nonnull env, jobject _Nonnull sessionObj);
 
-    APerformanceHintSession* createSessionUsingConfig(ASessionCreationConfig* sessionCreationConfig,
-                                                      hal::SessionTag tag = hal::SessionTag::APP,
-                                                      bool isJava = false);
+    int createSessionUsingConfig(ASessionCreationConfig* sessionCreationConfig,
+                                 APerformanceHintSession** sessionPtr,
+                                 hal::SessionTag tag = hal::SessionTag::APP, bool isJava = false);
     int64_t getPreferredRateNanos() const;
     int32_t getMaxGraphicsPipelineThreadsCount();
     FMQWrapper& getFMQWrapper();
@@ -202,6 +204,7 @@
                                          std::vector<T>& out);
     ndk::SpAIBinder& getToken();
     SupportInfoWrapper& getSupportInfo();
+    bool isFeatureSupported(APerformanceHintFeature feature);
 
 private:
     static APerformanceHintManager* create(std::shared_ptr<IHintManager> iHintManager);
@@ -239,8 +242,8 @@
     int setPreferPowerEfficiency(bool enabled);
     int reportActualWorkDuration(AWorkDuration* workDuration);
     bool isJava();
-    status_t setNativeSurfaces(ANativeWindow** windows, int numWindows, ASurfaceControl** controls,
-                               int numSurfaceControls);
+    status_t setNativeSurfaces(ANativeWindow** windows, size_t numWindows,
+                               ASurfaceControl** controls, size_t numSurfaceControls);
 
 private:
     friend struct APerformanceHintManager;
@@ -294,14 +297,12 @@
 
 // ===================================== SupportInfoWrapper implementation
 
-SupportInfoWrapper::SupportInfoWrapper(hal::SupportInfo& info) : mSupportInfo(info) {}
-
 bool SupportInfoWrapper::isSessionHintSupported(hal::SessionHint hint) {
-    return getEnumSupportFromBitfield(hint, mSupportInfo.sessionHints);
+    return getEnumSupportFromBitfield(hint, sessionHints);
 }
 
 bool SupportInfoWrapper::isSessionModeSupported(hal::SessionMode mode) {
-    return getEnumSupportFromBitfield(mode, mSupportInfo.sessionModes);
+    return getEnumSupportFromBitfield(mode, sessionModes);
 }
 
 // ===================================== APerformanceHintManager implementation
@@ -386,12 +387,14 @@
             .targetWorkDurationNanos = initialTargetWorkDurationNanos,
     }};
 
-    return APerformanceHintManager::createSessionUsingConfig(&creationConfig, tag, isJava);
+    APerformanceHintSession* sessionOut;
+    APerformanceHintManager::createSessionUsingConfig(&creationConfig, &sessionOut, tag, isJava);
+    return sessionOut;
 }
 
-APerformanceHintSession* APerformanceHintManager::createSessionUsingConfig(
-        ASessionCreationConfig* sessionCreationConfig, hal::SessionTag tag, bool isJava) {
-    std::shared_ptr<IHintSession> session;
+int APerformanceHintManager::createSessionUsingConfig(ASessionCreationConfig* sessionCreationConfig,
+                                                      APerformanceHintSession** sessionOut,
+                                                      hal::SessionTag tag, bool isJava) {
     hal::SessionConfig sessionConfig{.id = -1};
     ndk::ScopedAStatus ret;
 
@@ -411,31 +414,65 @@
         }
     }
 
+    bool autoCpu = sessionCreationConfig->hasMode(hal::SessionMode::AUTO_CPU);
+    bool autoGpu = sessionCreationConfig->hasMode(hal::SessionMode::AUTO_GPU);
+
+    if (autoCpu || autoGpu) {
+        LOG_ALWAYS_FATAL_IF(!sessionCreationConfig->hasMode(hal::SessionMode::GRAPHICS_PIPELINE),
+                            "Automatic session timing enabled without graphics pipeline mode");
+    }
+
+    if (autoCpu && !mSupportInfoWrapper.isSessionModeSupported(hal::SessionMode::AUTO_CPU)) {
+        ALOGE("Automatic CPU timing enabled but not supported");
+        return ENOTSUP;
+    }
+
+    if (autoGpu && !mSupportInfoWrapper.isSessionModeSupported(hal::SessionMode::AUTO_GPU)) {
+        ALOGE("Automatic GPU timing enabled but not supported");
+        return ENOTSUP;
+    }
+
+    IHintManager::SessionCreationReturn returnValue;
     ret = mHintManager->createHintSessionWithConfig(mToken, tag,
                                                     *static_cast<SessionCreationConfig*>(
                                                             sessionCreationConfig),
-                                                    &sessionConfig, &session);
+                                                    &sessionConfig, &returnValue);
 
     sessionCreationConfig->layerTokens.clear();
 
-    if (!ret.isOk() || !session) {
+    if (!ret.isOk() || !returnValue.session) {
         ALOGE("%s: PerformanceHint cannot create session. %s", __FUNCTION__, ret.getMessage());
-        return nullptr;
+        switch (ret.getExceptionCode()) {
+            case binder::Status::EX_UNSUPPORTED_OPERATION:
+                return ENOTSUP;
+            case binder::Status::EX_ILLEGAL_ARGUMENT:
+                return EINVAL;
+            default:
+                return EPIPE;
+        }
     }
 
-    auto out = new APerformanceHintSession(mHintManager, std::move(session),
+    auto out = new APerformanceHintSession(mHintManager, std::move(returnValue.session),
                                            mClientData.preferredRateNanos,
                                            sessionCreationConfig->targetWorkDurationNanos, isJava,
                                            sessionConfig.id == -1
                                                    ? std::nullopt
                                                    : std::make_optional<hal::SessionConfig>(
                                                              std::move(sessionConfig)));
+
+    *sessionOut = out;
+
     std::scoped_lock lock(sHintMutex);
     out->traceThreads(sessionCreationConfig->tids);
     out->traceTargetDuration(sessionCreationConfig->targetWorkDurationNanos);
     out->traceModes(sessionCreationConfig->modesToEnable);
 
-    return out;
+    if (returnValue.pipelineThreadLimitExceeded) {
+        ALOGE("Graphics pipeline session thread limit exceeded!");
+        return EBUSY;
+    }
+
+    return 0;
 }
 
 APerformanceHintSession* APerformanceHintManager::getSessionFromJava(JNIEnv* env,
@@ -480,6 +517,25 @@
     return mSupportInfoWrapper;
 }
 
+bool APerformanceHintManager::isFeatureSupported(APerformanceHintFeature feature) {
+    switch (feature) {
+        case (APERF_HINT_SESSIONS):
+            return mSupportInfoWrapper.usesSessions;
+        case (APERF_HINT_POWER_EFFICIENCY):
+            return mSupportInfoWrapper.isSessionModeSupported(hal::SessionMode::POWER_EFFICIENCY);
+        case (APERF_HINT_SURFACE_BINDING):
+            return mSupportInfoWrapper.compositionData.isSupported;
+        case (APERF_HINT_GRAPHICS_PIPELINE):
+            return mSupportInfoWrapper.isSessionModeSupported(hal::SessionMode::GRAPHICS_PIPELINE);
+        case (APERF_HINT_AUTO_CPU):
+            return mSupportInfoWrapper.isSessionModeSupported(hal::SessionMode::AUTO_CPU);
+        case (APERF_HINT_AUTO_GPU):
+            return mSupportInfoWrapper.isSessionModeSupported(hal::SessionMode::AUTO_GPU);
+        default:
+            return false;
+    }
+}
+
 // ===================================== APerformanceHintSession implementation
 
 constexpr int kNumEnums = enum_size<hal::SessionHint>();
@@ -512,10 +568,6 @@
 }
 
 int APerformanceHintSession::updateTargetWorkDuration(int64_t targetDurationNanos) {
-    if (targetDurationNanos <= 0) {
-        ALOGE("%s: targetDurationNanos must be positive", __FUNCTION__);
-        return EINVAL;
-    }
     std::scoped_lock lock(sHintMutex);
     if (mTargetDurationNanos == targetDurationNanos) {
         return 0;
@@ -546,7 +598,6 @@
                                    .workPeriodStartTimestampNanos = 0,
                                    .cpuDurationNanos = actualDurationNanos,
                                    .gpuDurationNanos = 0};
-
     return reportActualWorkDurationInternal(static_cast<AWorkDuration*>(&workDuration));
 }
 
@@ -556,17 +607,24 @@
 
 int APerformanceHintSession::sendHints(std::vector<hal::SessionHint>& hints, int64_t now,
                                        const char*) {
-    std::scoped_lock lock(sHintMutex);
+    auto& supportInfo = APerformanceHintManager::getInstance()->getSupportInfo();
+
+    // Drop all unsupported hints, there's not much point reporting errors or warnings for this
+    std::erase_if(hints,
+                  [&](hal::SessionHint hint) { return !supportInfo.isSessionHintSupported(hint); });
+
     if (hints.empty()) {
-        return EINVAL;
-    }
-    for (auto&& hint : hints) {
-        if (static_cast<int32_t>(hint) < 0 || static_cast<int32_t>(hint) >= kNumEnums) {
-            ALOGE("%s: invalid session hint %d", __FUNCTION__, hint);
-            return EINVAL;
-        }
+        // We successfully sent all hints we were able to, technically
+        return 0;
     }
 
+    for (auto&& hint : hints) {
+        LOG_ALWAYS_FATAL_IF(static_cast<int32_t>(hint) < 0 ||
+                                    static_cast<int32_t>(hint) >= kNumEnums,
+                            "%s: invalid session hint %d", __FUNCTION__, hint);
+    }
+
+    std::scoped_lock lock(sHintMutex);
     if (useNewLoadHintBehavior()) {
         if (!APerformanceHintManager::getInstance()->canSendLoadHints(hints, now)) {
             return EBUSY;
@@ -575,7 +633,7 @@
     // keep old rate limiter behavior for legacy flag
     else {
         for (auto&& hint : hints) {
-            if (now < (mLastHintSentTimestamp[static_cast<int32_t>(hint)] + SEND_HINT_TIMEOUT)) {
+            if (now < (mLastHintSentTimestamp[static_cast<int32_t>(hint)] + kSendHintTimeout)) {
                 return EBUSY;
             }
         }
@@ -651,7 +709,9 @@
     }
     std::vector<int32_t> tids(threadIds, threadIds + size);
     ndk::ScopedAStatus ret = mHintManager->setHintSessionThreads(mHintSession, tids);
-    if (!ret.isOk()) {
+
+    // Illegal state means there were too many graphics pipeline threads
+    if (!ret.isOk() && ret.getExceptionCode() != EX_SERVICE_SPECIFIC) {
         ALOGE("%s: failed: %s", __FUNCTION__, ret.getMessage());
         if (ret.getExceptionCode() == EX_ILLEGAL_ARGUMENT) {
             return EINVAL;
@@ -663,8 +723,10 @@
 
     std::scoped_lock lock(sHintMutex);
     traceThreads(tids);
+    bool tooManyThreads =
+            ret.getExceptionCode() == EX_SERVICE_SPECIFIC && ret.getServiceSpecificError() == 5;
 
-    return 0;
+    return tooManyThreads ? EBUSY : 0;
 }
 
 int APerformanceHintSession::getThreadIds(int32_t* const threadIds, size_t* size) {
@@ -711,10 +773,16 @@
 
 int APerformanceHintSession::reportActualWorkDurationInternal(AWorkDuration* workDuration) {
     int64_t actualTotalDurationNanos = workDuration->durationNanos;
-    traceActualDuration(workDuration->durationNanos);
     int64_t now = uptimeNanos();
     workDuration->timeStampNanos = now;
     std::scoped_lock lock(sHintMutex);
+
+    if (mTargetDurationNanos <= 0) {
+        ALOGE("Cannot report work durations if the target duration is not positive.");
+        return EINVAL;
+    }
+
+    traceActualDuration(actualTotalDurationNanos);
     mActualWorkDurations.push_back(std::move(*workDuration));
 
     if (actualTotalDurationNanos >= mTargetDurationNanos) {
@@ -757,9 +825,9 @@
     return 0;
 }
 
-status_t APerformanceHintSession::setNativeSurfaces(ANativeWindow** windows, int numWindows,
+status_t APerformanceHintSession::setNativeSurfaces(ANativeWindow** windows, size_t numWindows,
                                                     ASurfaceControl** controls,
-                                                    int numSurfaceControls) {
+                                                    size_t numSurfaceControls) {
     if (!mSessionConfig.has_value()) {
         return ENOTSUP;
     }
@@ -774,7 +842,10 @@
         ndkLayerHandles.emplace_back(ndk::SpAIBinder(AIBinder_fromPlatformBinder(handle)));
     }
 
-    mHintSession->associateToLayers(ndkLayerHandles);
+    auto ret = mHintSession->associateToLayers(ndkLayerHandles);
+    if (!ret.isOk()) {
+        return EPIPE;
+    }
     return 0;
 }
 
@@ -857,6 +928,11 @@
             }
             return true;
         });
+
+        // If we're unit testing the FMQ, we should block for it to finish completing
+        if (gForceFMQEnabled.has_value()) {
+            mChannelCreationFinished.wait();
+        }
     }
     return isActive();
 }
@@ -1029,7 +1105,8 @@
     ATrace_setCounter((mSessionName + " target duration").c_str(), targetDuration);
 }
 
-// ===================================== C API
+// ===================================== Start of C API
+
 APerformanceHintManager* APerformanceHint_getManager() {
     return APerformanceHintManager::getInstance();
 }
@@ -1037,10 +1114,16 @@
 #define VALIDATE_PTR(ptr) \
     LOG_ALWAYS_FATAL_IF(ptr == nullptr, "%s: " #ptr " is nullptr", __FUNCTION__);
 
+#define HARD_VALIDATE_INT(value, cmp)                                        \
+    LOG_ALWAYS_FATAL_IF(!(value cmp),                                        \
+                        "%s: Invalid value. Check failed: (" #value " " #cmp \
+                        ") with value: %" PRIi64,                            \
+                        __FUNCTION__, static_cast<int64_t>(value));
+
 #define VALIDATE_INT(value, cmp)                                                             \
     if (!(value cmp)) {                                                                      \
         ALOGE("%s: Invalid value. Check failed: (" #value " " #cmp ") with value: %" PRIi64, \
-              __FUNCTION__, value);                                                          \
+              __FUNCTION__, static_cast<int64_t>(value));                                    \
         return EINVAL;                                                                       \
     }
 
@@ -1058,19 +1141,27 @@
     return manager->createSession(threadIds, size, initialTargetWorkDurationNanos);
 }
 
-APerformanceHintSession* APerformanceHint_createSessionUsingConfig(
-        APerformanceHintManager* manager, ASessionCreationConfig* sessionCreationConfig) {
+int APerformanceHint_createSessionUsingConfig(APerformanceHintManager* manager,
+                                              ASessionCreationConfig* sessionCreationConfig,
+                                              APerformanceHintSession** sessionOut) {
     VALIDATE_PTR(manager);
     VALIDATE_PTR(sessionCreationConfig);
-    return manager->createSessionUsingConfig(sessionCreationConfig);
+    VALIDATE_PTR(sessionOut);
+    *sessionOut = nullptr;
+
+    return manager->createSessionUsingConfig(sessionCreationConfig, sessionOut);
 }
 
-APerformanceHintSession* APerformanceHint_createSessionUsingConfigInternal(
-        APerformanceHintManager* manager, ASessionCreationConfig* sessionCreationConfig,
-        SessionTag tag) {
+int APerformanceHint_createSessionUsingConfigInternal(APerformanceHintManager* manager,
+                                                      ASessionCreationConfig* sessionCreationConfig,
+                                                      APerformanceHintSession** sessionOut,
+                                                      SessionTag tag) {
     VALIDATE_PTR(manager);
     VALIDATE_PTR(sessionCreationConfig);
-    return manager->createSessionUsingConfig(sessionCreationConfig,
+    VALIDATE_PTR(sessionOut);
+    *sessionOut = nullptr;
+
+    return manager->createSessionUsingConfig(sessionCreationConfig, sessionOut,
                                              static_cast<hal::SessionTag>(tag));
 }
 
@@ -1111,6 +1202,7 @@
 int APerformanceHint_updateTargetWorkDuration(APerformanceHintSession* session,
                                               int64_t targetDurationNanos) {
     VALIDATE_PTR(session)
+    VALIDATE_INT(targetDurationNanos, >= 0)
     return session->updateTargetWorkDuration(targetDurationNanos);
 }
 
@@ -1204,13 +1296,23 @@
 }
 
 int APerformanceHint_setNativeSurfaces(APerformanceHintSession* session,
-                                       ANativeWindow** nativeWindows, int nativeWindowsSize,
-                                       ASurfaceControl** surfaceControls, int surfaceControlsSize) {
+                                       ANativeWindow** nativeWindows, size_t nativeWindowsSize,
+                                       ASurfaceControl** surfaceControls,
+                                       size_t surfaceControlsSize) {
     VALIDATE_PTR(session)
     return session->setNativeSurfaces(nativeWindows, nativeWindowsSize, surfaceControls,
                                       surfaceControlsSize);
 }
 
+bool APerformanceHint_isFeatureSupported(APerformanceHintFeature feature) {
+    APerformanceHintManager* manager = APerformanceHintManager::getInstance();
+    if (manager == nullptr) {
+        // Clearly whatever it is isn't supported in this case
+        return false;
+    }
+    return manager->isFeatureSupported(feature);
+}
+
 AWorkDuration* AWorkDuration_create() {
     return new AWorkDuration();
 }
@@ -1265,78 +1367,32 @@
 
 void ASessionCreationConfig_release(ASessionCreationConfig* config) {
     VALIDATE_PTR(config)
-
     delete config;
 }
 
-int ASessionCreationConfig_setTids(ASessionCreationConfig* config, const pid_t* tids, size_t size) {
+void ASessionCreationConfig_setTids(ASessionCreationConfig* config, const pid_t* tids,
+                                    size_t size) {
     VALIDATE_PTR(config)
     VALIDATE_PTR(tids)
+    HARD_VALIDATE_INT(size, > 0)
 
-    if (!useGraphicsPipeline()) {
-        return ENOTSUP;
-    }
-
-    if (size <= 0) {
-        LOG_ALWAYS_FATAL_IF(size <= 0,
-                            "%s: Invalid value. Thread id list size should be greater than zero.",
-                            __FUNCTION__);
-        return EINVAL;
-    }
     config->tids = std::vector<int32_t>(tids, tids + size);
-    return 0;
 }
 
-int ASessionCreationConfig_setTargetWorkDurationNanos(ASessionCreationConfig* config,
-                                                      int64_t targetWorkDurationNanos) {
+void ASessionCreationConfig_setTargetWorkDurationNanos(ASessionCreationConfig* config,
+                                                       int64_t targetWorkDurationNanos) {
     VALIDATE_PTR(config)
-    VALIDATE_INT(targetWorkDurationNanos, >= 0)
-
-    if (!useGraphicsPipeline()) {
-        return ENOTSUP;
-    }
-
     config->targetWorkDurationNanos = targetWorkDurationNanos;
-    return 0;
 }
 
-int ASessionCreationConfig_setPreferPowerEfficiency(ASessionCreationConfig* config, bool enabled) {
+void ASessionCreationConfig_setPreferPowerEfficiency(ASessionCreationConfig* config, bool enabled) {
     VALIDATE_PTR(config)
-
-    if (!useGraphicsPipeline()) {
-        return ENOTSUP;
-    }
-
-    if (enabled) {
-        config->modesToEnable.push_back(hal::SessionMode::POWER_EFFICIENCY);
-    } else {
-        std::erase(config->modesToEnable, hal::SessionMode::POWER_EFFICIENCY);
-    }
-    return 0;
+    config->setMode(hal::SessionMode::POWER_EFFICIENCY, enabled);
 }
 
-int ASessionCreationConfig_setGraphicsPipeline(ASessionCreationConfig* config, bool enabled) {
+void ASessionCreationConfig_setGraphicsPipeline(ASessionCreationConfig* config, bool enabled) {
     VALIDATE_PTR(config)
-
-    if (!useGraphicsPipeline()) {
-        return ENOTSUP;
-    }
-
-    if (enabled) {
-        config->modesToEnable.push_back(hal::SessionMode::GRAPHICS_PIPELINE);
-    } else {
-        std::erase(config->modesToEnable, hal::SessionMode::GRAPHICS_PIPELINE);
-
-        // Remove automatic timing modes if we turn off GRAPHICS_PIPELINE,
-        // as it is a strict pre-requisite for these to run
-        std::erase(config->modesToEnable, hal::SessionMode::AUTO_CPU);
-        std::erase(config->modesToEnable, hal::SessionMode::AUTO_GPU);
-    }
-    return 0;
-}
-
-void APerformanceHint_setUseGraphicsPipelineForTesting(bool enabled) {
-    kForceGraphicsPipeline = enabled;
+    config->setMode(hal::SessionMode::GRAPHICS_PIPELINE, enabled);
 }
 
 void APerformanceHint_getRateLimiterPropertiesForTesting(int32_t* maxLoadHintsPerInterval,
@@ -1349,47 +1405,21 @@
     kForceNewHintBehavior = newBehavior;
 }
 
-int ASessionCreationConfig_setNativeSurfaces(ASessionCreationConfig* config,
-                                             ANativeWindow** nativeWindows, int nativeWindowsSize,
-                                             ASurfaceControl** surfaceControls,
-                                             int surfaceControlsSize) {
+void ASessionCreationConfig_setNativeSurfaces(ASessionCreationConfig* config,
+                                              ANativeWindow** nativeWindows,
+                                              size_t nativeWindowsSize,
+                                              ASurfaceControl** surfaceControls,
+                                              size_t surfaceControlsSize) {
     VALIDATE_PTR(config)
-
     APerformanceHintManager::layersFromNativeSurfaces<wp<IBinder>>(nativeWindows, nativeWindowsSize,
                                                                    surfaceControls,
                                                                    surfaceControlsSize,
                                                                    config->layers);
-
-    if (config->layers.empty()) {
-        return EINVAL;
-    }
-
-    return 0;
 }
 
-int ASessionCreationConfig_setUseAutoTiming(ASessionCreationConfig* _Nonnull config, bool cpu,
-                                            bool gpu) {
+void ASessionCreationConfig_setUseAutoTiming(ASessionCreationConfig* _Nonnull config, bool cpu,
+                                             bool gpu) {
     VALIDATE_PTR(config)
-    if ((cpu || gpu) && !config->hasMode(hal::SessionMode::GRAPHICS_PIPELINE)) {
-        ALOGE("Automatic timing is not supported unless graphics pipeline mode is enabled first");
-        return ENOTSUP;
-    }
-
-    if (config->hasMode(hal::SessionMode::AUTO_CPU)) {
-        if (!cpu) {
-            std::erase(config->modesToEnable, hal::SessionMode::AUTO_CPU);
-        }
-    } else if (cpu) {
-        config->modesToEnable.push_back(static_cast<hal::SessionMode>(hal::SessionMode::AUTO_CPU));
-    }
-
-    if (config->hasMode(hal::SessionMode::AUTO_GPU)) {
-        if (!gpu) {
-            std::erase(config->modesToEnable, hal::SessionMode::AUTO_GPU);
-        }
-    } else if (gpu) {
-        config->modesToEnable.push_back(static_cast<hal::SessionMode>(hal::SessionMode::AUTO_GPU));
-    }
-
-    return 0;
+    config->setMode(hal::SessionMode::AUTO_CPU, cpu);
+    config->setMode(hal::SessionMode::AUTO_GPU, gpu);
 }
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index e3c10f6..f68fa1a 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -49,12 +49,87 @@
 using namespace android;
 using namespace testing;
 
+constexpr int64_t DEFAULT_TARGET_NS = 16666666L;
+
+template <class T, void (*D)(T*)>
+std::shared_ptr<T> wrapSP(T* incoming) {
+    return incoming == nullptr ? nullptr : std::shared_ptr<T>(incoming, [](T* ptr) { D(ptr); });
+}
+constexpr auto&& wrapSession = wrapSP<APerformanceHintSession, APerformanceHint_closeSession>;
+constexpr auto&& wrapConfig = wrapSP<ASessionCreationConfig, ASessionCreationConfig_release>;
+constexpr auto&& wrapWorkDuration = wrapSP<AWorkDuration, AWorkDuration_release>;
+
+std::shared_ptr<ASessionCreationConfig> createConfig() {
+    return wrapConfig(ASessionCreationConfig_create());
+}
+
+struct ConfigCreator {
+    std::vector<int32_t> tids{1, 2};
+    int64_t targetDuration = DEFAULT_TARGET_NS;
+    bool powerEfficient = false;
+    bool graphicsPipeline = false;
+    std::vector<ANativeWindow*> nativeWindows{};
+    std::vector<ASurfaceControl*> surfaceControls{};
+    bool autoCpu = false;
+    bool autoGpu = false;
+};
+
+struct SupportHelper {
+    bool hintSessions : 1;
+    bool powerEfficiency : 1;
+    bool bindToSurface : 1;
+    bool graphicsPipeline : 1;
+    bool autoCpu : 1;
+    bool autoGpu : 1;
+};
+
+SupportHelper getSupportHelper() {
+    return {
+            .hintSessions = APerformanceHint_isFeatureSupported(APERF_HINT_SESSIONS),
+            .powerEfficiency = APerformanceHint_isFeatureSupported(APERF_HINT_POWER_EFFICIENCY),
+            .bindToSurface = APerformanceHint_isFeatureSupported(APERF_HINT_SURFACE_BINDING),
+            .graphicsPipeline = APerformanceHint_isFeatureSupported(APERF_HINT_GRAPHICS_PIPELINE),
+            .autoCpu = APerformanceHint_isFeatureSupported(APERF_HINT_AUTO_CPU),
+            .autoGpu = APerformanceHint_isFeatureSupported(APERF_HINT_AUTO_GPU),
+    };
+}
+
+SupportHelper getFullySupportedSupportHelper() {
+    return {
+            .hintSessions = true,
+            .powerEfficiency = true,
+            .graphicsPipeline = true,
+            .autoCpu = true,
+            .autoGpu = true,
+    };
+}
+
+std::shared_ptr<ASessionCreationConfig> configFromCreator(ConfigCreator&& creator) {
+    auto config = createConfig();
+
+    ASessionCreationConfig_setTids(config.get(), creator.tids.data(), creator.tids.size());
+    ASessionCreationConfig_setTargetWorkDurationNanos(config.get(), creator.targetDuration);
+    ASessionCreationConfig_setPreferPowerEfficiency(config.get(), creator.powerEfficient);
+    ASessionCreationConfig_setGraphicsPipeline(config.get(), creator.graphicsPipeline);
+    ASessionCreationConfig_setNativeSurfaces(config.get(),
+                                             creator.nativeWindows.size() > 0
+                                                     ? creator.nativeWindows.data()
+                                                     : nullptr,
+                                             creator.nativeWindows.size(),
+                                             creator.surfaceControls.size() > 0
+                                                     ? creator.surfaceControls.data()
+                                                     : nullptr,
+                                             creator.surfaceControls.size());
+    ASessionCreationConfig_setUseAutoTiming(config.get(), creator.autoCpu, creator.autoGpu);
+    return config;
+}
+
 class MockIHintManager : public IHintManager {
 public:
     MOCK_METHOD(ScopedAStatus, createHintSessionWithConfig,
                 (const SpAIBinder& token, hal::SessionTag tag,
                  const SessionCreationConfig& creationConfig, hal::SessionConfig* config,
-                 std::shared_ptr<IHintSession>* _aidl_return),
+                 IHintManager::SessionCreationReturn* _aidl_return),
                 (override));
     MOCK_METHOD(ScopedAStatus, setHintSessionThreads,
                 (const std::shared_ptr<IHintSession>& hintSession,
@@ -115,8 +190,9 @@
         APerformanceHint_getRateLimiterPropertiesForTesting(&mMaxLoadHintsPerInterval,
                                                             &mLoadHintInterval);
         APerformanceHint_setIHintManagerForTesting(&mMockIHintManager);
-        APerformanceHint_setUseGraphicsPipelineForTesting(true);
         APerformanceHint_setUseNewLoadHintBehaviorForTesting(true);
+        mTids.push_back(1);
+        mTids.push_back(2);
     }
 
     void TearDown() override {
@@ -130,20 +206,22 @@
         ON_CALL(*mMockIHintManager, registerClient(_, _))
                 .WillByDefault(
                         DoAll(SetArgPointee<1>(mClientData), [] { return ScopedAStatus::ok(); }));
+        ON_CALL(*mMockIHintManager, isRemote()).WillByDefault(Return(true));
         return APerformanceHint_getManager();
     }
 
-    APerformanceHintSession* createSession(APerformanceHintManager* manager,
-                                           int64_t targetDuration = 56789L, bool isHwui = false) {
+    void prepareSessionMock() {
         mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
         const int64_t sessionId = 123;
-        std::vector<int32_t> tids;
-        tids.push_back(1);
-        tids.push_back(2);
+
+        mSessionCreationReturn = IHintManager::SessionCreationReturn{
+                .session = mMockSession,
+                .pipelineThreadLimitExceeded = false,
+        };
 
         ON_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _))
                 .WillByDefault(DoAll(SetArgPointee<3>(hal::SessionConfig({.id = sessionId})),
-                                     SetArgPointee<4>(std::shared_ptr<IHintSession>(mMockSession)),
+                                     SetArgPointee<4>(mSessionCreationReturn),
                                      [] { return ScopedAStatus::ok(); }));
 
         ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
@@ -161,48 +239,36 @@
         ON_CALL(*mMockSession, reportActualWorkDuration2(_)).WillByDefault([] {
             return ScopedAStatus::ok();
         });
-        if (isHwui) {
-            return APerformanceHint_createSessionInternal(manager, tids.data(), tids.size(),
-                                                          targetDuration, SessionTag::HWUI);
-        }
-        return APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
     }
 
-    APerformanceHintSession* createSessionUsingConfig(APerformanceHintManager* manager,
-                                                      SessionCreationConfig config,
-                                                      bool isHwui = false) {
-        mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
-        const int64_t sessionId = 123;
-
-        ON_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _))
-                .WillByDefault(DoAll(SetArgPointee<3>(hal::SessionConfig({.id = sessionId})),
-                                     SetArgPointee<4>(std::shared_ptr<IHintSession>(mMockSession)),
-                                     [] { return ScopedAStatus::ok(); }));
-
-        ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
-            return ScopedAStatus::ok();
-        });
-        ON_CALL(*mMockSession, sendHint(_)).WillByDefault([] { return ScopedAStatus::ok(); });
-        ON_CALL(*mMockSession, setMode(_, true)).WillByDefault([] { return ScopedAStatus::ok(); });
-        ON_CALL(*mMockSession, close()).WillByDefault([] { return ScopedAStatus::ok(); });
-        ON_CALL(*mMockSession, updateTargetWorkDuration(_)).WillByDefault([] {
-            return ScopedAStatus::ok();
-        });
-        ON_CALL(*mMockSession, reportActualWorkDuration(_, _)).WillByDefault([] {
-            return ScopedAStatus::ok();
-        });
-        ON_CALL(*mMockSession, reportActualWorkDuration2(_)).WillByDefault([] {
-            return ScopedAStatus::ok();
-        });
-
+    std::shared_ptr<APerformanceHintSession> createSession(APerformanceHintManager* manager,
+                                                           int64_t targetDuration = 56789L,
+                                                           bool isHwui = false) {
+        prepareSessionMock();
         if (isHwui) {
-            return APerformanceHint_createSessionUsingConfigInternal(
-                    manager, reinterpret_cast<ASessionCreationConfig*>(&config), SessionTag::HWUI);
+            return wrapSession(APerformanceHint_createSessionInternal(manager, mTids.data(),
+                                                                      mTids.size(), targetDuration,
+                                                                      SessionTag::HWUI));
+        }
+        return wrapSession(APerformanceHint_createSession(manager, mTids.data(), mTids.size(),
+                                                          targetDuration));
+    }
+
+    std::shared_ptr<APerformanceHintSession> createSessionUsingConfig(
+            APerformanceHintManager* manager, std::shared_ptr<ASessionCreationConfig>& config,
+            bool isHwui = false) {
+        prepareSessionMock();
+        APerformanceHintSession* session;
+        int out = 0;
+        if (isHwui) {
+            out = APerformanceHint_createSessionUsingConfigInternal(manager, config.get(), &session,
+                                                                    SessionTag::HWUI);
         }
 
-        return APerformanceHint_createSessionUsingConfig(manager,
-                                                         reinterpret_cast<ASessionCreationConfig*>(
-                                                                 &config));
+        out = APerformanceHint_createSessionUsingConfig(manager, config.get(), &session);
+        EXPECT_EQ(out, 0);
+
+        return wrapSession(session);
     }
 
     void setFMQEnabled(bool enabled) {
@@ -233,11 +299,13 @@
     uint32_t mWriteBits = 0x00000002;
     std::shared_ptr<NiceMock<MockIHintManager>> mMockIHintManager = nullptr;
     std::shared_ptr<NiceMock<MockIHintSession>> mMockSession = nullptr;
+    IHintManager::SessionCreationReturn mSessionCreationReturn;
     std::shared_ptr<AidlMessageQueue<hal::ChannelMessage, SynchronizedReadWrite>> mMockFMQ;
     std::shared_ptr<AidlMessageQueue<int8_t, SynchronizedReadWrite>> mMockFlagQueue;
     hardware::EventFlag* mEventFlag;
     int kMockQueueSize = 20;
     bool mUsingFMQ = false;
+    std::vector<int> mTids;
 
     IHintManager::HintManagerClientData mClientData{
             .powerHalVersion = 6,
@@ -273,107 +341,109 @@
 
 TEST_F(PerformanceHintTest, TestSession) {
     APerformanceHintManager* manager = createManager();
-    APerformanceHintSession* session = createSession(manager);
+    auto&& session = createSession(manager);
     ASSERT_TRUE(session);
 
     int64_t targetDurationNanos = 10;
     EXPECT_CALL(*mMockSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
-    int result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
+    int result = APerformanceHint_updateTargetWorkDuration(session.get(), targetDurationNanos);
     EXPECT_EQ(0, result);
 
     // subsequent call with same target should be ignored but return no error
-    result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
+    result = APerformanceHint_updateTargetWorkDuration(session.get(), targetDurationNanos);
     EXPECT_EQ(0, result);
 
+    Mock::VerifyAndClearExpectations(mMockSession.get());
+
     usleep(2); // Sleep for longer than preferredUpdateRateNanos.
     int64_t actualDurationNanos = 20;
     std::vector<int64_t> actualDurations;
     actualDurations.push_back(20);
     EXPECT_CALL(*mMockSession, reportActualWorkDuration2(_)).Times(Exactly(1));
-    result = APerformanceHint_reportActualWorkDuration(session, actualDurationNanos);
+    EXPECT_CALL(*mMockSession, updateTargetWorkDuration(_)).Times(Exactly(1));
+    result = APerformanceHint_reportActualWorkDuration(session.get(), actualDurationNanos);
     EXPECT_EQ(0, result);
-    result = APerformanceHint_updateTargetWorkDuration(session, -1L);
+    result = APerformanceHint_reportActualWorkDuration(session.get(), -1L);
     EXPECT_EQ(EINVAL, result);
-    result = APerformanceHint_reportActualWorkDuration(session, -1L);
+    result = APerformanceHint_updateTargetWorkDuration(session.get(), 0);
+    EXPECT_EQ(0, result);
+    result = APerformanceHint_updateTargetWorkDuration(session.get(), -2);
+    EXPECT_EQ(EINVAL, result);
+    result = APerformanceHint_reportActualWorkDuration(session.get(), 12L);
     EXPECT_EQ(EINVAL, result);
 
     SessionHint hintId = SessionHint::CPU_LOAD_RESET;
     EXPECT_CALL(*mMockSession, sendHint(Eq(hintId))).Times(Exactly(1));
-    result = APerformanceHint_sendHint(session, hintId);
+    result = APerformanceHint_sendHint(session.get(), hintId);
     EXPECT_EQ(0, result);
     EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::CPU_LOAD_UP))).Times(Exactly(1));
-    result = APerformanceHint_notifyWorkloadIncrease(session, true, false, "Test hint");
+    result = APerformanceHint_notifyWorkloadIncrease(session.get(), true, false, "Test hint");
     EXPECT_EQ(0, result);
     EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::CPU_LOAD_RESET))).Times(Exactly(1));
     EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::GPU_LOAD_RESET))).Times(Exactly(1));
-    result = APerformanceHint_notifyWorkloadReset(session, true, true, "Test hint");
+    result = APerformanceHint_notifyWorkloadReset(session.get(), true, true, "Test hint");
     EXPECT_EQ(0, result);
     EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::CPU_LOAD_SPIKE))).Times(Exactly(1));
     EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::GPU_LOAD_SPIKE))).Times(Exactly(1));
-    result = APerformanceHint_notifyWorkloadSpike(session, true, true, "Test hint");
+    result = APerformanceHint_notifyWorkloadSpike(session.get(), true, true, "Test hint");
     EXPECT_EQ(0, result);
 
-    result = APerformanceHint_sendHint(session, static_cast<SessionHint>(-1));
-    EXPECT_EQ(EINVAL, result);
+    EXPECT_DEATH(
+            { APerformanceHint_sendHint(session.get(), static_cast<SessionHint>(-1)); },
+            "invalid session hint");
 
     Mock::VerifyAndClearExpectations(mMockSession.get());
     for (int i = 0; i < mMaxLoadHintsPerInterval; ++i) {
-        APerformanceHint_sendHint(session, hintId);
+        APerformanceHint_sendHint(session.get(), hintId);
     }
 
     // Expect to get rate limited if we try to send faster than the limiter allows
     EXPECT_CALL(*mMockSession, sendHint(_)).Times(Exactly(0));
-    result = APerformanceHint_notifyWorkloadIncrease(session, true, true, "Test hint");
+    result = APerformanceHint_notifyWorkloadIncrease(session.get(), true, true, "Test hint");
     EXPECT_EQ(result, EBUSY);
     EXPECT_CALL(*mMockSession, sendHint(_)).Times(Exactly(0));
-    result = APerformanceHint_notifyWorkloadReset(session, true, true, "Test hint");
+    result = APerformanceHint_notifyWorkloadReset(session.get(), true, true, "Test hint");
     EXPECT_CALL(*mMockSession, close()).Times(Exactly(1));
-    APerformanceHint_closeSession(session);
 }
 
 TEST_F(PerformanceHintTest, TestUpdatedSessionCreation) {
     EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _)).Times(1);
     APerformanceHintManager* manager = createManager();
-    APerformanceHintSession* session = createSession(manager);
+    auto&& session = createSession(manager);
     ASSERT_TRUE(session);
-    APerformanceHint_closeSession(session);
 }
 
 TEST_F(PerformanceHintTest, TestSessionCreationUsingConfig) {
     EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _)).Times(1);
-    SessionCreationConfig config{.tids = std::vector<int32_t>(1, 2),
-                                 .targetWorkDurationNanos = 5678,
-                                 .modesToEnable = std::vector<hal::SessionMode>(0)};
+    auto&& config = configFromCreator({.tids = mTids});
     APerformanceHintManager* manager = createManager();
-    APerformanceHintSession* session = createSessionUsingConfig(manager, config);
+    auto&& session = createSessionUsingConfig(manager, config);
     ASSERT_TRUE(session);
-    APerformanceHint_closeSession(session);
 }
 
 TEST_F(PerformanceHintTest, TestHwuiSessionCreation) {
     EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, hal::SessionTag::HWUI, _, _, _))
             .Times(1);
     APerformanceHintManager* manager = createManager();
-    APerformanceHintSession* session = createSession(manager, 56789L, true);
+    auto&& session = createSession(manager, 56789L, true);
     ASSERT_TRUE(session);
-    APerformanceHint_closeSession(session);
 }
 
 TEST_F(PerformanceHintTest, SetThreads) {
     APerformanceHintManager* manager = createManager();
 
-    APerformanceHintSession* session = createSession(manager);
+    auto&& session = createSession(manager);
     ASSERT_TRUE(session);
 
     int32_t emptyTids[2];
-    int result = APerformanceHint_setThreads(session, emptyTids, 0);
+    int result = APerformanceHint_setThreads(session.get(), emptyTids, 0);
     EXPECT_EQ(EINVAL, result);
 
     std::vector<int32_t> newTids;
     newTids.push_back(1);
     newTids.push_back(3);
     EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(newTids))).Times(Exactly(1));
-    result = APerformanceHint_setThreads(session, newTids.data(), newTids.size());
+    result = APerformanceHint_setThreads(session.get(), newTids.data(), newTids.size());
     EXPECT_EQ(0, result);
 
     testing::Mock::VerifyAndClearExpectations(mMockIHintManager.get());
@@ -383,27 +453,27 @@
     EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(invalidTids)))
             .Times(Exactly(1))
             .WillOnce(Return(ByMove(ScopedAStatus::fromExceptionCode(EX_SECURITY))));
-    result = APerformanceHint_setThreads(session, invalidTids.data(), invalidTids.size());
+    result = APerformanceHint_setThreads(session.get(), invalidTids.data(), invalidTids.size());
     EXPECT_EQ(EPERM, result);
 }
 
 TEST_F(PerformanceHintTest, SetPowerEfficient) {
     APerformanceHintManager* manager = createManager();
-    APerformanceHintSession* session = createSession(manager);
+    auto&& session = createSession(manager);
     ASSERT_TRUE(session);
 
     EXPECT_CALL(*mMockSession, setMode(_, Eq(true))).Times(Exactly(1));
-    int result = APerformanceHint_setPreferPowerEfficiency(session, true);
+    int result = APerformanceHint_setPreferPowerEfficiency(session.get(), true);
     EXPECT_EQ(0, result);
 
     EXPECT_CALL(*mMockSession, setMode(_, Eq(false))).Times(Exactly(1));
-    result = APerformanceHint_setPreferPowerEfficiency(session, false);
+    result = APerformanceHint_setPreferPowerEfficiency(session.get(), false);
     EXPECT_EQ(0, result);
 }
 
 TEST_F(PerformanceHintTest, CreateZeroTargetDurationSession) {
     APerformanceHintManager* manager = createManager();
-    APerformanceHintSession* session = createSession(manager, 0);
+    auto&& session = createSession(manager, 0);
     ASSERT_TRUE(session);
 }
 
@@ -428,12 +498,12 @@
 
 TEST_F(PerformanceHintTest, TestAPerformanceHint_reportActualWorkDuration2) {
     APerformanceHintManager* manager = createManager();
-    APerformanceHintSession* session = createSession(manager);
+    auto&& session = createSession(manager);
     ASSERT_TRUE(session);
 
     int64_t targetDurationNanos = 10;
     EXPECT_CALL(*mMockSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
-    int result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
+    int result = APerformanceHint_updateTargetWorkDuration(session.get(), targetDurationNanos);
     EXPECT_EQ(0, result);
 
     usleep(2); // Sleep for longer than preferredUpdateRateNanos.
@@ -452,54 +522,53 @@
 
         EXPECT_CALL(*mMockSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
                 .Times(Exactly(pair.expectedResult == OK));
-        result = APerformanceHint_reportActualWorkDuration2(session,
+        result = APerformanceHint_reportActualWorkDuration2(session.get(),
                                                             reinterpret_cast<AWorkDuration*>(
                                                                     &pair.duration));
         EXPECT_EQ(pair.expectedResult, result);
     }
 
     EXPECT_CALL(*mMockSession, close()).Times(Exactly(1));
-    APerformanceHint_closeSession(session);
 }
 
 TEST_F(PerformanceHintTest, TestAWorkDuration) {
-    AWorkDuration* aWorkDuration = AWorkDuration_create();
+    // AWorkDuration* aWorkDuration = AWorkDuration_create();
+    auto&& aWorkDuration = wrapWorkDuration(AWorkDuration_create());
     ASSERT_NE(aWorkDuration, nullptr);
 
-    AWorkDuration_setWorkPeriodStartTimestampNanos(aWorkDuration, 1);
-    AWorkDuration_setActualTotalDurationNanos(aWorkDuration, 20);
-    AWorkDuration_setActualCpuDurationNanos(aWorkDuration, 13);
-    AWorkDuration_setActualGpuDurationNanos(aWorkDuration, 8);
-    AWorkDuration_release(aWorkDuration);
+    AWorkDuration_setWorkPeriodStartTimestampNanos(aWorkDuration.get(), 1);
+    AWorkDuration_setActualTotalDurationNanos(aWorkDuration.get(), 20);
+    AWorkDuration_setActualCpuDurationNanos(aWorkDuration.get(), 13);
+    AWorkDuration_setActualGpuDurationNanos(aWorkDuration.get(), 8);
 }
 
 TEST_F(PerformanceHintTest, TestCreateUsingFMQ) {
     setFMQEnabled(true);
     APerformanceHintManager* manager = createManager();
-    APerformanceHintSession* session = createSession(manager);
+    auto&& session = createSession(manager);
     ASSERT_TRUE(session);
 }
 
 TEST_F(PerformanceHintTest, TestUpdateTargetWorkDurationUsingFMQ) {
     setFMQEnabled(true);
     APerformanceHintManager* manager = createManager();
-    APerformanceHintSession* session = createSession(manager);
-    APerformanceHint_updateTargetWorkDuration(session, 456);
+    auto&& session = createSession(manager);
+    APerformanceHint_updateTargetWorkDuration(session.get(), 456);
     expectToReadFromFmq<HalChannelMessageContents::Tag::targetDuration>(456);
 }
 
 TEST_F(PerformanceHintTest, TestSendHintUsingFMQ) {
     setFMQEnabled(true);
     APerformanceHintManager* manager = createManager();
-    APerformanceHintSession* session = createSession(manager);
-    APerformanceHint_sendHint(session, SessionHint::CPU_LOAD_UP);
+    auto&& session = createSession(manager);
+    APerformanceHint_sendHint(session.get(), SessionHint::CPU_LOAD_UP);
     expectToReadFromFmq<HalChannelMessageContents::Tag::hint>(hal::SessionHint::CPU_LOAD_UP);
 }
 
 TEST_F(PerformanceHintTest, TestReportActualUsingFMQ) {
     setFMQEnabled(true);
     APerformanceHintManager* manager = createManager();
-    APerformanceHintSession* session = createSession(manager);
+    auto&& session = createSession(manager);
     hal::WorkDuration duration{.timeStampNanos = 3,
                                .durationNanos = 999999,
                                .workPeriodStartTimestampNanos = 1,
@@ -513,20 +582,91 @@
             .gpuDurationNanos = duration.gpuDurationNanos,
     };
 
-    APerformanceHint_reportActualWorkDuration2(session,
+    APerformanceHint_reportActualWorkDuration2(session.get(),
                                                reinterpret_cast<AWorkDuration*>(&duration));
     expectToReadFromFmq<HalChannelMessageContents::Tag::workDuration>(durationExpected);
 }
 
 TEST_F(PerformanceHintTest, TestASessionCreationConfig) {
-    ASessionCreationConfig* config = ASessionCreationConfig_create();
-    ASSERT_NE(config, nullptr);
+    auto&& config = configFromCreator({
+            .tids = mTids,
+            .targetDuration = 20,
+            .powerEfficient = true,
+            .graphicsPipeline = true,
+    });
 
-    const int32_t testTids[2] = {1, 2};
-    const size_t size = 2;
-    EXPECT_EQ(ASessionCreationConfig_setTids(config, testTids, size), 0);
-    EXPECT_EQ(ASessionCreationConfig_setTargetWorkDurationNanos(config, 20), 0);
-    EXPECT_EQ(ASessionCreationConfig_setPreferPowerEfficiency(config, true), 0);
-    EXPECT_EQ(ASessionCreationConfig_setGraphicsPipeline(config, true), 0);
-    ASessionCreationConfig_release(config);
+    APerformanceHintManager* manager = createManager();
+    auto&& session = createSessionUsingConfig(manager, config);
+
+    ASSERT_NE(session, nullptr);
+    ASSERT_NE(config, nullptr);
+}
+
+TEST_F(PerformanceHintTest, TestSupportObject) {
+    // Disable GPU and Power Efficiency support to test partial enabling
+    mClientData.supportInfo.sessionModes &= ~(1 << (int)hal::SessionMode::AUTO_GPU);
+    mClientData.supportInfo.sessionHints &= ~(1 << (int)hal::SessionHint::GPU_LOAD_UP);
+    mClientData.supportInfo.sessionHints &= ~(1 << (int)hal::SessionHint::POWER_EFFICIENCY);
+
+    APerformanceHintManager* manager = createManager();
+
+    union {
+        int expectedSupportInt;
+        SupportHelper expectedSupport;
+    };
+
+    union {
+        int actualSupportInt;
+        SupportHelper actualSupport;
+    };
+
+    expectedSupport = getFullySupportedSupportHelper();
+    actualSupport = getSupportHelper();
+
+    expectedSupport.autoGpu = false;
+
+    EXPECT_EQ(expectedSupportInt, actualSupportInt);
+}
+
+TEST_F(PerformanceHintTest, TestCreatingAutoSession) {
+    // Disable GPU capability for testing
+    mClientData.supportInfo.sessionModes &= ~(1 << (int)hal::SessionMode::AUTO_GPU);
+    APerformanceHintManager* manager = createManager();
+
+    auto&& invalidConfig = configFromCreator({
+            .tids = mTids,
+            .targetDuration = 20,
+            .graphicsPipeline = false,
+            .autoCpu = true,
+            .autoGpu = true,
+    });
+
+    EXPECT_DEATH({ createSessionUsingConfig(manager, invalidConfig); }, "");
+
+    auto&& unsupportedConfig = configFromCreator({
+            .tids = mTids,
+            .targetDuration = 20,
+            .graphicsPipeline = true,
+            .autoCpu = true,
+            .autoGpu = true,
+    });
+
+    APerformanceHintSession* unsupportedSession = nullptr;
+
+    // Creating a session with auto timing but no graphics pipeline should fail
+    int out = APerformanceHint_createSessionUsingConfig(manager, unsupportedConfig.get(),
+                                                        &unsupportedSession);
+    EXPECT_EQ(out, ENOTSUP);
+    EXPECT_EQ(wrapSession(unsupportedSession), nullptr);
+
+    auto&& validConfig = configFromCreator({
+            .tids = mTids,
+            .targetDuration = 20,
+            .graphicsPipeline = true,
+            .autoCpu = true,
+            .autoGpu = false,
+    });
+
+    auto&& validSession = createSessionUsingConfig(manager, validConfig);
+    EXPECT_NE(validSession, nullptr);
 }
diff --git a/nfc/Android.bp b/nfc/Android.bp
deleted file mode 100644
index 0fdb3bd..0000000
--- a/nfc/Android.bp
+++ /dev/null
@@ -1,79 +0,0 @@
-package {
-    default_team: "trendy_team_fwk_nfc",
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-filegroup {
-    name: "framework-nfc-updatable-sources",
-    path: "java",
-    srcs: [
-        "java/**/*.java",
-        "java/**/*.aidl",
-    ],
-    visibility: [
-        "//frameworks/base:__subpackages__",
-        "//packages/apps/Nfc:__subpackages__",
-        "//packages/modules/Nfc:__subpackages__",
-    ],
-}
-
-java_sdk_library {
-    name: "framework-nfc",
-    libs: [
-        "androidx.annotation_annotation",
-        "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
-        "framework-permission-s.stubs.module_lib",
-        "framework-permission.stubs.module_lib",
-    ],
-    stub_only_libs: [
-        // Needed for javadoc references.
-        "framework-permission-s.stubs.module_lib",
-    ],
-    static_libs: [
-        "android.nfc.flags-aconfig-java",
-        "android.permission.flags-aconfig-java",
-    ],
-    srcs: [
-        ":framework-nfc-updatable-sources",
-        ":framework-nfc-javastream-protos",
-    ],
-    defaults: ["framework-module-defaults"],
-    sdk_version: "module_current",
-    min_sdk_version: "35", // Make it 36 once available.
-    installable: true,
-    optimize: {
-        enabled: false,
-    },
-    hostdex: true, // for hiddenapi check
-    permitted_packages: [
-        "android.nfc",
-        "com.android.nfc",
-    ],
-    impl_library_visibility: [
-        "//frameworks/base:__subpackages__",
-        "//cts:__subpackages__",
-        "//packages/apps/Nfc:__subpackages__",
-        "//packages/modules/Nfc:__subpackages__",
-    ],
-    jarjar_rules: ":nfc-jarjar-rules",
-    lint: {
-        baseline_filename: "lint-baseline.xml",
-    },
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.nfcservices",
-    ],
-    aconfig_declarations: [
-        "android.nfc.flags-aconfig",
-    ],
-}
-
-filegroup {
-    name: "nfc-jarjar-rules",
-    srcs: ["jarjar-rules.txt"],
-}
diff --git a/nfc/OWNERS b/nfc/OWNERS
deleted file mode 100644
index f46dccd..0000000
--- a/nfc/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48448
-include platform/packages/apps/Nfc:/OWNERS
\ No newline at end of file
diff --git a/nfc/TEST_MAPPING b/nfc/TEST_MAPPING
deleted file mode 100644
index 49c778d..0000000
--- a/nfc/TEST_MAPPING
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "NfcManagerTests"
-    },
-    {
-      "name": "CtsNfcTestCases"
-    },
-    {
-      "name": "CtsNdefTestCases"
-    }
-  ]
-}
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
deleted file mode 100644
index c8c479a..0000000
--- a/nfc/api/current.txt
+++ /dev/null
@@ -1,495 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
-  public final class AvailableNfcAntenna implements android.os.Parcelable {
-    ctor public AvailableNfcAntenna(int, int);
-    method public int describeContents();
-    method public int getLocationX();
-    method public int getLocationY();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.AvailableNfcAntenna> CREATOR;
-  }
-
-  public class FormatException extends java.lang.Exception {
-    ctor public FormatException();
-    ctor public FormatException(String);
-    ctor public FormatException(String, Throwable);
-  }
-
-  public final class NdefMessage implements android.os.Parcelable {
-    ctor public NdefMessage(byte[]) throws android.nfc.FormatException;
-    ctor public NdefMessage(android.nfc.NdefRecord, android.nfc.NdefRecord...);
-    ctor public NdefMessage(android.nfc.NdefRecord[]);
-    method public int describeContents();
-    method public int getByteArrayLength();
-    method public android.nfc.NdefRecord[] getRecords();
-    method public byte[] toByteArray();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NdefMessage> CREATOR;
-  }
-
-  public final class NdefRecord implements android.os.Parcelable {
-    ctor public NdefRecord(short, byte[], byte[], byte[]);
-    ctor @Deprecated public NdefRecord(byte[]) throws android.nfc.FormatException;
-    method public static android.nfc.NdefRecord createApplicationRecord(String);
-    method public static android.nfc.NdefRecord createExternal(String, String, byte[]);
-    method public static android.nfc.NdefRecord createMime(String, byte[]);
-    method public static android.nfc.NdefRecord createTextRecord(String, String);
-    method public static android.nfc.NdefRecord createUri(android.net.Uri);
-    method public static android.nfc.NdefRecord createUri(String);
-    method public int describeContents();
-    method public byte[] getId();
-    method public byte[] getPayload();
-    method public short getTnf();
-    method public byte[] getType();
-    method @Deprecated public byte[] toByteArray();
-    method public String toMimeType();
-    method public android.net.Uri toUri();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NdefRecord> CREATOR;
-    field public static final byte[] RTD_ALTERNATIVE_CARRIER;
-    field public static final byte[] RTD_HANDOVER_CARRIER;
-    field public static final byte[] RTD_HANDOVER_REQUEST;
-    field public static final byte[] RTD_HANDOVER_SELECT;
-    field public static final byte[] RTD_SMART_POSTER;
-    field public static final byte[] RTD_TEXT;
-    field public static final byte[] RTD_URI;
-    field public static final short TNF_ABSOLUTE_URI = 3; // 0x3
-    field public static final short TNF_EMPTY = 0; // 0x0
-    field public static final short TNF_EXTERNAL_TYPE = 4; // 0x4
-    field public static final short TNF_MIME_MEDIA = 2; // 0x2
-    field public static final short TNF_UNCHANGED = 6; // 0x6
-    field public static final short TNF_UNKNOWN = 5; // 0x5
-    field public static final short TNF_WELL_KNOWN = 1; // 0x1
-  }
-
-  public final class NfcAdapter {
-    method @FlaggedApi("android.nfc.nfc_state_change") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable();
-    method public void disableForegroundDispatch(android.app.Activity);
-    method public void disableReaderMode(android.app.Activity);
-    method @FlaggedApi("android.nfc.nfc_state_change") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable();
-    method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]);
-    method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle);
-    method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
-    method @Nullable public android.nfc.NfcAntennaInfo getNfcAntennaInfo();
-    method @FlaggedApi("android.nfc.enable_nfc_charging") @Nullable public android.nfc.WlcListenerDeviceInfo getWlcListenerDeviceInfo();
-    method public boolean ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler);
-    method public boolean isEnabled();
-    method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean isObserveModeEnabled();
-    method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean isObserveModeSupported();
-    method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionEnabled();
-    method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionSupported();
-    method public boolean isSecureNfcEnabled();
-    method public boolean isSecureNfcSupported();
-    method @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public boolean isTagIntentAllowed();
-    method @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public boolean isTagIntentAppPreferenceSupported();
-    method @FlaggedApi("android.nfc.enable_nfc_charging") public boolean isWlcEnabled();
-    method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void resetDiscoveryTechnology(@NonNull android.app.Activity);
-    method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void setDiscoveryTechnology(@NonNull android.app.Activity, int, int);
-    method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setObserveModeEnabled(boolean);
-    field public static final String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED";
-    field @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public static final String ACTION_CHANGE_TAG_INTENT_PREFERENCE = "android.nfc.action.CHANGE_TAG_INTENT_PREFERENCE";
-    field public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
-    field @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static final String ACTION_PREFERRED_PAYMENT_CHANGED = "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
-    field public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
-    field public static final String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED";
-    field @RequiresPermission(android.Manifest.permission.NFC_TRANSACTION_EVENT) public static final String ACTION_TRANSACTION_DETECTED = "android.nfc.action.TRANSACTION_DETECTED";
-    field public static final String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE";
-    field public static final String EXTRA_AID = "android.nfc.extra.AID";
-    field public static final String EXTRA_DATA = "android.nfc.extra.DATA";
-    field public static final String EXTRA_ID = "android.nfc.extra.ID";
-    field public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
-    field public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON = "android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON";
-    field public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
-    field public static final String EXTRA_SECURE_ELEMENT_NAME = "android.nfc.extra.SECURE_ELEMENT_NAME";
-    field public static final String EXTRA_TAG = "android.nfc.extra.TAG";
-    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_DISABLE = 0; // 0x0
-    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_KEEP = -2147483648; // 0x80000000
-    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_A = 1; // 0x1
-    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_B = 2; // 0x2
-    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_F = 4; // 0x4
-    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_READER_DISABLE = 0; // 0x0
-    field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_READER_KEEP = -2147483648; // 0x80000000
-    field public static final int FLAG_READER_NFC_A = 1; // 0x1
-    field public static final int FLAG_READER_NFC_B = 2; // 0x2
-    field public static final int FLAG_READER_NFC_BARCODE = 16; // 0x10
-    field public static final int FLAG_READER_NFC_F = 4; // 0x4
-    field public static final int FLAG_READER_NFC_V = 8; // 0x8
-    field public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 256; // 0x100
-    field public static final int FLAG_READER_SKIP_NDEF_CHECK = 128; // 0x80
-    field public static final int PREFERRED_PAYMENT_CHANGED = 2; // 0x2
-    field public static final int PREFERRED_PAYMENT_LOADED = 1; // 0x1
-    field public static final int PREFERRED_PAYMENT_UPDATED = 3; // 0x3
-    field public static final int STATE_OFF = 1; // 0x1
-    field public static final int STATE_ON = 3; // 0x3
-    field public static final int STATE_TURNING_OFF = 4; // 0x4
-    field public static final int STATE_TURNING_ON = 2; // 0x2
-  }
-
-  @Deprecated public static interface NfcAdapter.CreateBeamUrisCallback {
-    method @Deprecated public android.net.Uri[] createBeamUris(android.nfc.NfcEvent);
-  }
-
-  @Deprecated public static interface NfcAdapter.CreateNdefMessageCallback {
-    method @Deprecated public android.nfc.NdefMessage createNdefMessage(android.nfc.NfcEvent);
-  }
-
-  @Deprecated public static interface NfcAdapter.OnNdefPushCompleteCallback {
-    method @Deprecated public void onNdefPushComplete(android.nfc.NfcEvent);
-  }
-
-  public static interface NfcAdapter.OnTagRemovedListener {
-    method public void onTagRemoved();
-  }
-
-  public static interface NfcAdapter.ReaderCallback {
-    method public void onTagDiscovered(android.nfc.Tag);
-  }
-
-  public final class NfcAntennaInfo implements android.os.Parcelable {
-    ctor public NfcAntennaInfo(int, int, boolean, @NonNull java.util.List<android.nfc.AvailableNfcAntenna>);
-    method public int describeContents();
-    method @NonNull public java.util.List<android.nfc.AvailableNfcAntenna> getAvailableNfcAntennas();
-    method public int getDeviceHeight();
-    method public int getDeviceWidth();
-    method public boolean isDeviceFoldable();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NfcAntennaInfo> CREATOR;
-  }
-
-  public final class NfcEvent {
-    field public final android.nfc.NfcAdapter nfcAdapter;
-    field public final int peerLlcpMajorVersion;
-    field public final int peerLlcpMinorVersion;
-  }
-
-  public final class NfcManager {
-    method public android.nfc.NfcAdapter getDefaultAdapter();
-  }
-
-  public final class Tag implements android.os.Parcelable {
-    method public int describeContents();
-    method public byte[] getId();
-    method public String[] getTechList();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.Tag> CREATOR;
-  }
-
-  public class TagLostException extends java.io.IOException {
-    ctor public TagLostException();
-    ctor public TagLostException(String);
-  }
-
-  @FlaggedApi("android.nfc.enable_nfc_charging") public final class WlcListenerDeviceInfo implements android.os.Parcelable {
-    ctor public WlcListenerDeviceInfo(int, double, double, int);
-    method public int describeContents();
-    method @FloatRange(from=0.0, to=100.0) public double getBatteryLevel();
-    method public int getProductId();
-    method public int getState();
-    method public double getTemperature();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.WlcListenerDeviceInfo> CREATOR;
-    field public static final int STATE_CONNECTED_CHARGING = 2; // 0x2
-    field public static final int STATE_CONNECTED_DISCHARGING = 3; // 0x3
-    field public static final int STATE_DISCONNECTED = 1; // 0x1
-  }
-
-}
-
-package android.nfc.cardemulation {
-
-  public final class CardEmulation {
-    method public boolean categoryAllowsForegroundPreference(String);
-    method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public java.util.List<java.lang.String> getAidsForPreferredPaymentService();
-    method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, String);
-    method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public int getDefaultNfcSubscriptionId();
-    method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public CharSequence getDescriptionForPreferredPaymentService();
-    method public static android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter);
-    method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getRouteDestinationForPreferredPaymentService();
-    method public int getSelectionModeForCategory(String);
-    method public boolean isDefaultServiceForAid(android.content.ComponentName, String);
-    method public boolean isDefaultServiceForCategory(android.content.ComponentName, String);
-    method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public boolean isEuiccSupported();
-    method public boolean registerAidsForService(android.content.ComponentName, String, java.util.List<java.lang.String>);
-    method @FlaggedApi("android.nfc.nfc_event_listener") public void registerNfcEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.cardemulation.CardEmulation.NfcEventCallback);
-    method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
-    method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopPatternFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
-    method public boolean removeAidsForService(android.content.ComponentName, String);
-    method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean removePollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String);
-    method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean removePollingLoopPatternFilterForService(@NonNull android.content.ComponentName, @NonNull String);
-    method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean setOffHostForService(@NonNull android.content.ComponentName, @NonNull String);
-    method public boolean setPreferredService(android.app.Activity, android.content.ComponentName);
-    method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setShouldDefaultToObserveModeForService(@NonNull android.content.ComponentName, boolean);
-    method public boolean supportsAidPrefixRegistration();
-    method @FlaggedApi("android.nfc.nfc_event_listener") public void unregisterNfcEventCallback(@NonNull android.nfc.cardemulation.CardEmulation.NfcEventCallback);
-    method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean unsetOffHostForService(@NonNull android.content.ComponentName);
-    method public boolean unsetPreferredService(android.app.Activity);
-    field @Deprecated public static final String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
-    field public static final String CATEGORY_OTHER = "other";
-    field public static final String CATEGORY_PAYMENT = "payment";
-    field public static final String EXTRA_CATEGORY = "category";
-    field public static final String EXTRA_SERVICE_COMPONENT = "component";
-    field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_COMMAND_TIMEOUT = 3; // 0x3
-    field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_CRASH_RESTART = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR = 2; // 0x2
-    field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_UNKNOWN = 0; // 0x0
-    field @FlaggedApi("android.nfc.nfc_associated_role_services") public static final String PROPERTY_ALLOW_SHARED_ROLE_PRIORITY = "android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY";
-    field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT = 3; // 0x3
-    field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DH = 0; // 0x0
-    field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC = 2; // 0x2
-    field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET = -1; // 0xffffffff
-    field public static final int SELECTION_MODE_ALWAYS_ASK = 1; // 0x1
-    field public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2; // 0x2
-    field public static final int SELECTION_MODE_PREFER_DEFAULT = 0; // 0x0
-  }
-
-  @FlaggedApi("android.nfc.nfc_event_listener") public static interface CardEmulation.NfcEventCallback {
-    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidConflictOccurred(@NonNull String);
-    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidNotRouted(@NonNull String);
-    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onInternalErrorReported(int);
-    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onNfcStateChanged(int);
-    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onObserveModeStateChanged(boolean);
-    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onPreferredServiceChanged(boolean);
-    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onRemoteFieldChanged(boolean);
-  }
-
-  public abstract class HostApduService extends android.app.Service {
-    ctor public HostApduService();
-    method public final void notifyUnhandled();
-    method public final android.os.IBinder onBind(android.content.Intent);
-    method public abstract void onDeactivated(int);
-    method public abstract byte[] processCommandApdu(byte[], android.os.Bundle);
-    method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void processPollingFrames(@NonNull java.util.List<android.nfc.cardemulation.PollingFrame>);
-    method public final void sendResponseApdu(byte[]);
-    field public static final int DEACTIVATION_DESELECTED = 1; // 0x1
-    field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
-    field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_APDU_SERVICE";
-    field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.host_apdu_service";
-  }
-
-  public abstract class HostNfcFService extends android.app.Service {
-    ctor public HostNfcFService();
-    method public final android.os.IBinder onBind(android.content.Intent);
-    method public abstract void onDeactivated(int);
-    method public abstract byte[] processNfcFPacket(byte[], android.os.Bundle);
-    method public final void sendResponsePacket(byte[]);
-    field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
-    field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_NFCF_SERVICE";
-    field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.host_nfcf_service";
-  }
-
-  public final class NfcFCardEmulation {
-    method public boolean disableService(android.app.Activity) throws java.lang.RuntimeException;
-    method public boolean enableService(android.app.Activity, android.content.ComponentName) throws java.lang.RuntimeException;
-    method public static android.nfc.cardemulation.NfcFCardEmulation getInstance(android.nfc.NfcAdapter);
-    method public String getNfcid2ForService(android.content.ComponentName) throws java.lang.RuntimeException;
-    method public String getSystemCodeForService(android.content.ComponentName) throws java.lang.RuntimeException;
-    method public boolean registerSystemCodeForService(android.content.ComponentName, String) throws java.lang.RuntimeException;
-    method public boolean setNfcid2ForService(android.content.ComponentName, String) throws java.lang.RuntimeException;
-    method public boolean unregisterSystemCodeForService(android.content.ComponentName) throws java.lang.RuntimeException;
-  }
-
-  public abstract class OffHostApduService extends android.app.Service {
-    ctor public OffHostApduService();
-    field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE";
-    field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.off_host_apdu_service";
-  }
-
-  @FlaggedApi("android.nfc.nfc_read_polling_loop") public final class PollingFrame implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public byte[] getData();
-    method public long getTimestamp();
-    method public boolean getTriggeredAutoTransact();
-    method public int getType();
-    method public int getVendorSpecificGain();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.PollingFrame> CREATOR;
-    field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_A = 65; // 0x41
-    field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_B = 66; // 0x42
-    field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_F = 70; // 0x46
-    field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_OFF = 88; // 0x58
-    field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_ON = 79; // 0x4f
-    field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_UNKNOWN = 85; // 0x55
-  }
-
-}
-
-package android.nfc.tech {
-
-  public final class IsoDep implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.IsoDep get(android.nfc.Tag);
-    method public byte[] getHiLayerResponse();
-    method public byte[] getHistoricalBytes();
-    method public int getMaxTransceiveLength();
-    method public android.nfc.Tag getTag();
-    method public int getTimeout();
-    method public boolean isConnected();
-    method public boolean isExtendedLengthApduSupported();
-    method public void setTimeout(int);
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-  }
-
-  public final class MifareClassic implements android.nfc.tech.TagTechnology {
-    method public boolean authenticateSectorWithKeyA(int, byte[]) throws java.io.IOException;
-    method public boolean authenticateSectorWithKeyB(int, byte[]) throws java.io.IOException;
-    method public int blockToSector(int);
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public void decrement(int, int) throws java.io.IOException;
-    method public static android.nfc.tech.MifareClassic get(android.nfc.Tag);
-    method public int getBlockCount();
-    method public int getBlockCountInSector(int);
-    method public int getMaxTransceiveLength();
-    method public int getSectorCount();
-    method public int getSize();
-    method public android.nfc.Tag getTag();
-    method public int getTimeout();
-    method public int getType();
-    method public void increment(int, int) throws java.io.IOException;
-    method public boolean isConnected();
-    method public byte[] readBlock(int) throws java.io.IOException;
-    method public void restore(int) throws java.io.IOException;
-    method public int sectorToBlock(int);
-    method public void setTimeout(int);
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-    method public void transfer(int) throws java.io.IOException;
-    method public void writeBlock(int, byte[]) throws java.io.IOException;
-    field public static final int BLOCK_SIZE = 16; // 0x10
-    field public static final byte[] KEY_DEFAULT;
-    field public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY;
-    field public static final byte[] KEY_NFC_FORUM;
-    field public static final int SIZE_1K = 1024; // 0x400
-    field public static final int SIZE_2K = 2048; // 0x800
-    field public static final int SIZE_4K = 4096; // 0x1000
-    field public static final int SIZE_MINI = 320; // 0x140
-    field public static final int TYPE_CLASSIC = 0; // 0x0
-    field public static final int TYPE_PLUS = 1; // 0x1
-    field public static final int TYPE_PRO = 2; // 0x2
-    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
-  }
-
-  public final class MifareUltralight implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.MifareUltralight get(android.nfc.Tag);
-    method public int getMaxTransceiveLength();
-    method public android.nfc.Tag getTag();
-    method public int getTimeout();
-    method public int getType();
-    method public boolean isConnected();
-    method public byte[] readPages(int) throws java.io.IOException;
-    method public void setTimeout(int);
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-    method public void writePage(int, byte[]) throws java.io.IOException;
-    field public static final int PAGE_SIZE = 4; // 0x4
-    field public static final int TYPE_ULTRALIGHT = 1; // 0x1
-    field public static final int TYPE_ULTRALIGHT_C = 2; // 0x2
-    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
-  }
-
-  public final class Ndef implements android.nfc.tech.TagTechnology {
-    method public boolean canMakeReadOnly();
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.Ndef get(android.nfc.Tag);
-    method public android.nfc.NdefMessage getCachedNdefMessage();
-    method public int getMaxSize();
-    method public android.nfc.NdefMessage getNdefMessage() throws android.nfc.FormatException, java.io.IOException;
-    method public android.nfc.Tag getTag();
-    method public String getType();
-    method public boolean isConnected();
-    method public boolean isWritable();
-    method public boolean makeReadOnly() throws java.io.IOException;
-    method public void writeNdefMessage(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException;
-    field public static final String MIFARE_CLASSIC = "com.nxp.ndef.mifareclassic";
-    field public static final String NFC_FORUM_TYPE_1 = "org.nfcforum.ndef.type1";
-    field public static final String NFC_FORUM_TYPE_2 = "org.nfcforum.ndef.type2";
-    field public static final String NFC_FORUM_TYPE_3 = "org.nfcforum.ndef.type3";
-    field public static final String NFC_FORUM_TYPE_4 = "org.nfcforum.ndef.type4";
-  }
-
-  public final class NdefFormatable implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public void format(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException;
-    method public void formatReadOnly(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException;
-    method public static android.nfc.tech.NdefFormatable get(android.nfc.Tag);
-    method public android.nfc.Tag getTag();
-    method public boolean isConnected();
-  }
-
-  public final class NfcA implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.NfcA get(android.nfc.Tag);
-    method public byte[] getAtqa();
-    method public int getMaxTransceiveLength();
-    method public short getSak();
-    method public android.nfc.Tag getTag();
-    method public int getTimeout();
-    method public boolean isConnected();
-    method public void setTimeout(int);
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-  }
-
-  public final class NfcB implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.NfcB get(android.nfc.Tag);
-    method public byte[] getApplicationData();
-    method public int getMaxTransceiveLength();
-    method public byte[] getProtocolInfo();
-    method public android.nfc.Tag getTag();
-    method public boolean isConnected();
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-  }
-
-  public final class NfcBarcode implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.NfcBarcode get(android.nfc.Tag);
-    method public byte[] getBarcode();
-    method public android.nfc.Tag getTag();
-    method public int getType();
-    method public boolean isConnected();
-    field public static final int TYPE_KOVIO = 1; // 0x1
-    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
-  }
-
-  public final class NfcF implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.NfcF get(android.nfc.Tag);
-    method public byte[] getManufacturer();
-    method public int getMaxTransceiveLength();
-    method public byte[] getSystemCode();
-    method public android.nfc.Tag getTag();
-    method public int getTimeout();
-    method public boolean isConnected();
-    method public void setTimeout(int);
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-  }
-
-  public final class NfcV implements android.nfc.tech.TagTechnology {
-    method public void close() throws java.io.IOException;
-    method public void connect() throws java.io.IOException;
-    method public static android.nfc.tech.NfcV get(android.nfc.Tag);
-    method public byte getDsfId();
-    method public int getMaxTransceiveLength();
-    method public byte getResponseFlags();
-    method public android.nfc.Tag getTag();
-    method public boolean isConnected();
-    method public byte[] transceive(byte[]) throws java.io.IOException;
-  }
-
-  public interface TagTechnology extends java.io.Closeable {
-    method public void connect() throws java.io.IOException;
-    method public android.nfc.Tag getTag();
-    method public boolean isConnected();
-  }
-
-}
-
diff --git a/nfc/api/lint-baseline.txt b/nfc/api/lint-baseline.txt
deleted file mode 100644
index ef9aab6..0000000
--- a/nfc/api/lint-baseline.txt
+++ /dev/null
@@ -1,95 +0,0 @@
-// Baseline format: 1.0
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_ADAPTER_STATE_CHANGED:
-    Field 'ACTION_ADAPTER_STATE_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_PREFERRED_PAYMENT_CHANGED:
-    Field 'ACTION_PREFERRED_PAYMENT_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED:
-    Field 'ACTION_TRANSACTION_DETECTED' is missing @BroadcastBehavior
-
-
-MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent):
-    Missing nullability on method `onBind` return
-MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent) parameter #0:
-    Missing nullability on parameter `intent` in method `onBind`
-
-
-RequiresPermission: android.nfc.NfcAdapter#disableForegroundDispatch(android.app.Activity):
-    Method 'disableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.NfcAdapter#enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]):
-    Method 'enableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForAid(android.content.ComponentName, String):
-    Method 'isDefaultServiceForAid' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String):
-    Method 'isDefaultServiceForCategory' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#setOffHostForService(android.content.ComponentName, String):
-    Method 'setOffHostForService' documentation mentions permissions already declared by @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyA(int, byte[]):
-    Method 'authenticateSectorWithKeyA' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyB(int, byte[]):
-    Method 'authenticateSectorWithKeyB' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#decrement(int, int):
-    Method 'decrement' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#increment(int, int):
-    Method 'increment' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#readBlock(int):
-    Method 'readBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#restore(int):
-    Method 'restore' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transfer(int):
-    Method 'transfer' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#writeBlock(int, byte[]):
-    Method 'writeBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#readPages(int):
-    Method 'readPages' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#writePage(int, byte[]):
-    Method 'writePage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#getNdefMessage():
-    Method 'getNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#isWritable():
-    Method 'isWritable' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#makeReadOnly():
-    Method 'makeReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#writeNdefMessage(android.nfc.NdefMessage):
-    Method 'writeNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#format(android.nfc.NdefMessage):
-    Method 'format' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#formatReadOnly(android.nfc.NdefMessage):
-    Method 'formatReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcB#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcV#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#close():
-    Method 'close' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#connect():
-    Method 'connect' documentation mentions permissions without declaring @RequiresPermission
diff --git a/nfc/api/module-lib-current.txt b/nfc/api/module-lib-current.txt
deleted file mode 100644
index 5ebe911..0000000
--- a/nfc/api/module-lib-current.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
-  public class NfcFrameworkInitializer {
-    method public static void registerServiceWrappers();
-    method public static void setNfcServiceManager(@NonNull android.nfc.NfcServiceManager);
-  }
-
-}
-
diff --git a/nfc/api/module-lib-lint-baseline.txt b/nfc/api/module-lib-lint-baseline.txt
deleted file mode 100644
index f7f8ee3..0000000
--- a/nfc/api/module-lib-lint-baseline.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-// Baseline format: 1.0
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_ADAPTER_STATE_CHANGED:
-    Field 'ACTION_ADAPTER_STATE_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_PREFERRED_PAYMENT_CHANGED:
-    Field 'ACTION_PREFERRED_PAYMENT_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC:
-    Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED:
-    Field 'ACTION_TRANSACTION_DETECTED' is missing @BroadcastBehavior
-
-RequiresPermission: android.nfc.NfcAdapter#disableForegroundDispatch(android.app.Activity):
-    Method 'disableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.NfcAdapter#enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]):
-    Method 'enableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForAid(android.content.ComponentName, String):
-    Method 'isDefaultServiceForAid' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String):
-    Method 'isDefaultServiceForCategory' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#setOffHostForService(android.content.ComponentName, String):
-    Method 'setOffHostForService' documentation mentions permissions already declared by @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyA(int, byte[]):
-    Method 'authenticateSectorWithKeyA' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyB(int, byte[]):
-    Method 'authenticateSectorWithKeyB' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#decrement(int, int):
-    Method 'decrement' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#increment(int, int):
-    Method 'increment' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#readBlock(int):
-    Method 'readBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#restore(int):
-    Method 'restore' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transfer(int):
-    Method 'transfer' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#writeBlock(int, byte[]):
-    Method 'writeBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#readPages(int):
-    Method 'readPages' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#writePage(int, byte[]):
-    Method 'writePage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#getNdefMessage():
-    Method 'getNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#isWritable():
-    Method 'isWritable' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#makeReadOnly():
-    Method 'makeReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#writeNdefMessage(android.nfc.NdefMessage):
-    Method 'writeNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#format(android.nfc.NdefMessage):
-    Method 'format' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#formatReadOnly(android.nfc.NdefMessage):
-    Method 'formatReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcB#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcV#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#close():
-    Method 'close' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#connect():
-    Method 'connect' documentation mentions permissions without declaring @RequiresPermission
-
-SdkConstant: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC:
-    Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
diff --git a/nfc/api/module-lib-removed.txt b/nfc/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/nfc/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/nfc/api/removed.txt b/nfc/api/removed.txt
deleted file mode 100644
index fb82b5d..0000000
--- a/nfc/api/removed.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
-  public final class NfcAdapter {
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void disableForegroundNdefPush(android.app.Activity);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public boolean invokeBeam(android.app.Activity);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public boolean isNdefPushEnabled();
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setBeamPushUris(android.net.Uri[], android.app.Activity);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...);
-    method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...);
-  }
-
-}
-
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
deleted file mode 100644
index 6e69da1..0000000
--- a/nfc/api/system-current.txt
+++ /dev/null
@@ -1,256 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
-  public final class NfcAdapter {
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean addNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler, String[]);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable(boolean);
-    method @FlaggedApi("android.nfc.enable_nfc_reader_option") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableReaderOption(boolean);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
-    method @FlaggedApi("android.nfc.enable_nfc_mainline") public int getAdapterState();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public android.nfc.NfcOemExtension getNfcOemExtension();
-    method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int);
-    method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
-    method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported();
-    method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
-    method @FlaggedApi("android.nfc.nfc_vendor_cmd") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerNfcVendorNciCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.NfcVendorNciCallback);
-    method @FlaggedApi("android.nfc.enable_nfc_charging") public void registerWlcStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.WlcStateListener);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler);
-    method @FlaggedApi("android.nfc.nfc_vendor_cmd") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int sendVendorNciMessage(int, @IntRange(from=0, to=15) int, @IntRange(from=0) int, @NonNull byte[]);
-    method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean setControllerAlwaysOn(boolean);
-    method @FlaggedApi("android.nfc.enable_nfc_mainline") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setReaderModePollingEnabled(boolean);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setTagIntentAppPreferenceForUser(int, @NonNull String, boolean);
-    method @FlaggedApi("android.nfc.enable_nfc_charging") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setWlcEnabled(boolean);
-    method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void unregisterControllerAlwaysOnListener(@NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
-    method @FlaggedApi("android.nfc.nfc_vendor_cmd") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void unregisterNfcVendorNciCallback(@NonNull android.nfc.NfcAdapter.NfcVendorNciCallback);
-    method @FlaggedApi("android.nfc.enable_nfc_charging") public void unregisterWlcStateListener(@NonNull android.nfc.NfcAdapter.WlcStateListener);
-    field @FlaggedApi("android.nfc.enable_nfc_mainline") public static final String ACTION_REQUIRE_UNLOCK_FOR_NFC = "android.nfc.action.REQUIRE_UNLOCK_FOR_NFC";
-    field @FlaggedApi("android.nfc.enable_nfc_mainline") @RequiresPermission(android.Manifest.permission.SHOW_CUSTOMIZED_RESOLVER) public static final String ACTION_SHOW_NFC_RESOLVER = "android.nfc.action.SHOW_NFC_RESOLVER";
-    field @FlaggedApi("android.nfc.enable_nfc_mainline") public static final String EXTRA_RESOLVE_INFOS = "android.nfc.extra.RESOLVE_INFOS";
-    field @FlaggedApi("android.nfc.nfc_set_default_disc_tech") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static final int FLAG_SET_DEFAULT_TECH = 1073741824; // 0x40000000
-    field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int MESSAGE_TYPE_COMMAND = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_FAILED = 3; // 0x3
-    field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_MESSAGE_CORRUPTED = 2; // 0x2
-    field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_REJECTED = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_SUCCESS = 0; // 0x0
-    field public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1; // 0xffffffff
-    field public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0; // 0x0
-    field public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2; // 0xfffffffe
-  }
-
-  public static interface NfcAdapter.ControllerAlwaysOnListener {
-    method public void onControllerAlwaysOnChanged(boolean);
-  }
-
-  public static interface NfcAdapter.NfcUnlockHandler {
-    method public boolean onUnlockAttempted(android.nfc.Tag);
-  }
-
-  @FlaggedApi("android.nfc.nfc_vendor_cmd") public static interface NfcAdapter.NfcVendorNciCallback {
-    method @FlaggedApi("android.nfc.nfc_vendor_cmd") public void onVendorNciNotification(@IntRange(from=9, to=15) int, int, @NonNull byte[]);
-    method @FlaggedApi("android.nfc.nfc_vendor_cmd") public void onVendorNciResponse(@IntRange(from=0, to=15) int, int, @NonNull byte[]);
-  }
-
-  @FlaggedApi("android.nfc.enable_nfc_charging") public static interface NfcAdapter.WlcStateListener {
-    method public void onWlcStateChanged(@NonNull android.nfc.WlcListenerDeviceInfo);
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public final class NfcOemExtension {
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void clearPreference();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int forceRoutingTableCommit();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public java.util.Map<java.lang.String,java.lang.Integer> getActiveNfceeList();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public long getMaxPausePollingTimeoutMills();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.nfc.RoutingStatus getRoutingStatus();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.List<android.nfc.NfcRoutingTableEntry> getRoutingTable();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public android.nfc.T4tNdefNfcee getT4tNdefNfcee();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean hasUserEnabledNfc();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isAutoChangeEnabled();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagPresent();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void maybeTriggerFirmwareUpdate();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void overwriteRoutingTable(int, int, int, int);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int pausePolling(long);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcOemExtension.Callback);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int resumePolling();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setAutoChangeEnabled(boolean);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void setControllerAlwaysOnMode(int);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void synchronizeScreenState();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void triggerInitialization();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void unregisterCallback(@NonNull android.nfc.NfcOemExtension.Callback);
-    field public static final int COMMIT_ROUTING_STATUS_FAILED = 3; // 0x3
-    field public static final int COMMIT_ROUTING_STATUS_FAILED_UPDATE_IN_PROGRESS = 6; // 0x6
-    field public static final int COMMIT_ROUTING_STATUS_OK = 0; // 0x0
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int DISABLE = 0; // 0x0
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int ENABLE_DEFAULT = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int ENABLE_EE = 3; // 0x3
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int ENABLE_TRANSPARENT = 2; // 0x2
-    field public static final int HCE_ACTIVATE = 1; // 0x1
-    field public static final int HCE_DATA_TRANSFERRED = 2; // 0x2
-    field public static final int HCE_DEACTIVATE = 3; // 0x3
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_A = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_B = 2; // 0x2
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_F = 4; // 0x4
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_NONE = 0; // 0x0
-    field public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2; // 0x2
-    field public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1; // 0x1
-    field public static final int STATUS_OK = 0; // 0x0
-    field public static final int STATUS_UNKNOWN_ERROR = 1; // 0x1
-  }
-
-  public static interface NfcOemExtension.Callback {
-    method public void onApplyRouting(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onBootFinished(int);
-    method public void onBootStarted();
-    method public void onCardEmulationActivated(boolean);
-    method public void onDisableFinished(int);
-    method public void onDisableRequested(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onDisableStarted();
-    method public void onEeListenActivated(boolean);
-    method public void onEeUpdated();
-    method public void onEnableFinished(int);
-    method public void onEnableRequested(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onEnableStarted();
-    method public void onExtractOemPackages(@NonNull android.nfc.NdefMessage, @NonNull java.util.function.Consumer<java.util.List<java.lang.String>>);
-    method public void onGetOemAppSearchIntent(@NonNull java.util.List<java.lang.String>, @NonNull java.util.function.Consumer<android.content.Intent>);
-    method public void onHceEventReceived(int);
-    method public void onLaunchHceAppChooserActivity(@NonNull String, @NonNull java.util.List<android.nfc.cardemulation.ApduServiceInfo>, @NonNull android.content.ComponentName, @NonNull String);
-    method public void onLaunchHceTapAgainDialog(@NonNull android.nfc.cardemulation.ApduServiceInfo, @NonNull String);
-    method public void onLogEventNotified(@NonNull android.nfc.OemLogItems);
-    method public void onNdefMessage(@NonNull android.nfc.Tag, @NonNull android.nfc.NdefMessage, @NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onNdefRead(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onReaderOptionChanged(boolean);
-    method public void onRfDiscoveryStarted(boolean);
-    method public void onRfFieldDetected(boolean);
-    method public void onRoutingChanged(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onRoutingTableFull();
-    method public void onStateUpdated(int);
-    method public void onTagConnected(boolean);
-    method public void onTagDispatch(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public abstract class NfcRoutingTableEntry {
-    method public int getNfceeId();
-    method public int getRouteType();
-    method public int getType();
-    field public static final int TYPE_AID = 0; // 0x0
-    field public static final int TYPE_PROTOCOL = 1; // 0x1
-    field public static final int TYPE_SYSTEM_CODE = 3; // 0x3
-    field public static final int TYPE_TECHNOLOGY = 2; // 0x2
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public final class OemLogItems implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getAction();
-    method public int getCallingPid();
-    method @Nullable public byte[] getCommandApdu();
-    method public int getEvent();
-    method @Nullable public byte[] getResponseApdu();
-    method @Nullable public java.time.Instant getRfFieldEventTimeMillis();
-    method @Nullable public android.nfc.Tag getTag();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.OemLogItems> CREATOR;
-    field public static final int EVENT_DISABLE = 2; // 0x2
-    field public static final int EVENT_ENABLE = 1; // 0x1
-    field public static final int EVENT_UNSET = 0; // 0x0
-    field public static final int LOG_ACTION_HCE_DATA = 516; // 0x204
-    field public static final int LOG_ACTION_NFC_TOGGLE = 513; // 0x201
-    field public static final int LOG_ACTION_RF_FIELD_STATE_CHANGED = 1; // 0x1
-    field public static final int LOG_ACTION_SCREEN_STATE_CHANGED = 518; // 0x206
-    field public static final int LOG_ACTION_TAG_DETECTED = 3; // 0x3
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingStatus {
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultIsoDepRoute();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultOffHostRoute();
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultRoute();
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableAidEntry extends android.nfc.NfcRoutingTableEntry {
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public String getAid();
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableProtocolEntry extends android.nfc.NfcRoutingTableEntry {
-    method @FlaggedApi("android.nfc.nfc_oem_extension") public int getProtocol();
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_ISO_DEP = 4; // 0x4
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_NDEF = 7; // 0x7
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_NFC_DEP = 5; // 0x5
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T1T = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T2T = 2; // 0x2
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T3T = 3; // 0x3
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T5T = 6; // 0x6
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_UNDETERMINED = 0; // 0x0
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_UNSUPPORTED = -1; // 0xffffffff
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableSystemCodeEntry extends android.nfc.NfcRoutingTableEntry {
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public byte[] getSystemCode();
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableTechnologyEntry extends android.nfc.NfcRoutingTableEntry {
-    method @FlaggedApi("android.nfc.nfc_oem_extension") public int getTechnology();
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_A = 0; // 0x0
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_B = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_F = 2; // 0x2
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_UNSUPPORTED = -1; // 0xffffffff
-    field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_V = 3; // 0x3
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfcee {
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int clearData();
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isOperationOngoing();
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isSupported();
-    method @Nullable @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public android.nfc.T4tNdefNfceeCcFileInfo readCcfile();
-    method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public byte[] readData(@IntRange(from=0, to=65535) int);
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int writeData(@IntRange(from=0, to=65535) int, @NonNull byte[]);
-    field public static final int CLEAR_DATA_FAILED_DEVICE_BUSY = -1; // 0xffffffff
-    field public static final int CLEAR_DATA_FAILED_INTERNAL = 0; // 0x0
-    field public static final int CLEAR_DATA_SUCCESS = 1; // 0x1
-    field public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6; // 0xfffffffa
-    field public static final int WRITE_DATA_ERROR_DEVICE_BUSY = -9; // 0xfffffff7
-    field public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7; // 0xfffffff9
-    field public static final int WRITE_DATA_ERROR_INTERNAL = -1; // 0xffffffff
-    field public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4; // 0xfffffffc
-    field public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5; // 0xfffffffb
-    field public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8; // 0xfffffff8
-    field public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3; // 0xfffffffd
-    field public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2; // 0xfffffffe
-    field public static final int WRITE_DATA_SUCCESS = 0; // 0x0
-  }
-
-  @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfceeCcFileInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method @IntRange(from=15, to=32767) public int getCcFileLength();
-    method @IntRange(from=0xffffffff, to=65535) public int getFileId();
-    method @IntRange(from=5, to=32767) public int getMaxSize();
-    method public int getVersion();
-    method public boolean isReadAllowed();
-    method public boolean isWriteAllowed();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.T4tNdefNfceeCcFileInfo> CREATOR;
-    field public static final int VERSION_2_0 = 32; // 0x20
-    field public static final int VERSION_3_0 = 48; // 0x30
-  }
-
-}
-
-package android.nfc.cardemulation {
-
-  public final class CardEmulation {
-    method @FlaggedApi("android.permission.flags.wallet_role_enabled") @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static android.content.ComponentName getPreferredPaymentService(@NonNull android.content.Context);
-    method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public java.util.List<android.nfc.cardemulation.ApduServiceInfo> getServices(@NonNull String, int);
-    method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void overrideRoutingTable(@NonNull android.app.Activity, int, int);
-    method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void recoverRoutingTable(@NonNull android.app.Activity);
-    method @FlaggedApi("android.nfc.enable_card_emulation_euicc") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setDefaultNfcSubscriptionId(int);
-    method @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setServiceEnabledForCategoryOther(@NonNull android.content.ComponentName, boolean);
-    field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET = 3; // 0x3
-    field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED = 1; // 0x1
-    field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE = 2; // 0x2
-    field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR = 4; // 0x4
-    field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_OK = 0; // 0x0
-    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR = 2; // 0x2
-    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1; // 0x1
-    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3; // 0x3
-    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0; // 0x0
-    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_UNKNOWN = -1; // 0xffffffff
-  }
-
-}
-
diff --git a/nfc/api/system-lint-baseline.txt b/nfc/api/system-lint-baseline.txt
deleted file mode 100644
index c7a6181..0000000
--- a/nfc/api/system-lint-baseline.txt
+++ /dev/null
@@ -1,119 +0,0 @@
-// Baseline format: 1.0
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_ADAPTER_STATE_CHANGED:
-    Field 'ACTION_ADAPTER_STATE_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_PREFERRED_PAYMENT_CHANGED:
-    Field 'ACTION_PREFERRED_PAYMENT_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC:
-    Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED:
-    Field 'ACTION_TRANSACTION_DETECTED' is missing @BroadcastBehavior
-
-
-CallbackMethodName: android.nfc.NfcOemExtension.Callback#shouldSkipRoutingChange():
-    Callback method names must follow the on<Something> style: shouldSkipRoutingChange
-
-
-MethodNameTense: android.nfc.NfcOemExtension.Callback#onEnable():
-    Unexpected tense; probably meant `enabled`, was `onEnable`
-
-
-MissingNullability: android.nfc.cardemulation.CardEmulation#overrideRoutingTable(android.app.Activity, String, String) parameter #1:
-    Missing nullability on parameter `protocol` in method `overrideRoutingTable`
-MissingNullability: android.nfc.cardemulation.CardEmulation#overrideRoutingTable(android.app.Activity, String, String) parameter #2:
-    Missing nullability on parameter `technology` in method `overrideRoutingTable`
-MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent):
-    Missing nullability on method `onBind` return
-MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent) parameter #0:
-    Missing nullability on parameter `intent` in method `onBind`
-
-
-RequiresPermission: android.nfc.NfcAdapter#disableForegroundDispatch(android.app.Activity):
-    Method 'disableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.NfcAdapter#enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]):
-    Method 'enableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForAid(android.content.ComponentName, String):
-    Method 'isDefaultServiceForAid' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String):
-    Method 'isDefaultServiceForCategory' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#setOffHostForService(android.content.ComponentName, String):
-    Method 'setOffHostForService' documentation mentions permissions already declared by @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyA(int, byte[]):
-    Method 'authenticateSectorWithKeyA' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyB(int, byte[]):
-    Method 'authenticateSectorWithKeyB' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#decrement(int, int):
-    Method 'decrement' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#increment(int, int):
-    Method 'increment' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#readBlock(int):
-    Method 'readBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#restore(int):
-    Method 'restore' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transfer(int):
-    Method 'transfer' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#writeBlock(int, byte[]):
-    Method 'writeBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#readPages(int):
-    Method 'readPages' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#writePage(int, byte[]):
-    Method 'writePage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#getNdefMessage():
-    Method 'getNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#isWritable():
-    Method 'isWritable' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#makeReadOnly():
-    Method 'makeReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#writeNdefMessage(android.nfc.NdefMessage):
-    Method 'writeNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#format(android.nfc.NdefMessage):
-    Method 'format' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#formatReadOnly(android.nfc.NdefMessage):
-    Method 'formatReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcB#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#getTimeout():
-    Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#setTimeout(int):
-    Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcV#transceive(byte[]):
-    Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#close():
-    Method 'close' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#connect():
-    Method 'connect' documentation mentions permissions without declaring @RequiresPermission
-
-
-SamShouldBeLast: android.nfc.NfcAdapter#enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle):
-    SAM-compatible parameters (such as parameter 2, "callback", in android.nfc.NfcAdapter.enableReaderMode) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
-SamShouldBeLast: android.nfc.NfcAdapter#ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler):
-    SAM-compatible parameters (such as parameter 3, "tagRemovedListener", in android.nfc.NfcAdapter.ignore) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
-
-
-SdkConstant: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC:
-    Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
diff --git a/nfc/api/system-removed.txt b/nfc/api/system-removed.txt
deleted file mode 100644
index c6eaa57..0000000
--- a/nfc/api/system-removed.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
-  public final class NfcAdapter {
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disableNdefPush();
-    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush();
-    method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int);
-    field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1
-  }
-
-}
-
diff --git a/nfc/api/test-current.txt b/nfc/api/test-current.txt
deleted file mode 100644
index d802177..0000000
--- a/nfc/api/test-current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/nfc/api/test-removed.txt b/nfc/api/test-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/nfc/api/test-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/nfc/jarjar-rules.txt b/nfc/jarjar-rules.txt
deleted file mode 100644
index 63a6a58..0000000
--- a/nfc/jarjar-rules.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-# Used by framework-nfc for proto debug dumping
-rule android.app.PendingIntentProto* com.android.nfc.x.@0
-rule android.content.ComponentNameProto* com.android.nfc.x.@0
-rule android.content.IntentProto* com.android.nfc.x.@0
-rule android.content.IntentFilterProto* com.android.nfc.x.@0
-rule android.content.AuthorityEntryProto* com.android.nfc.x.@0
-rule android.content.UriRelativeFilter* com.android.nfc.x.@0
-rule android.nfc.cardemulation.AidGroupProto* com.android.nfc.x.@0
-rule android.nfc.cardemulation.ApduServiceInfoProto* com.android.nfc.x.@0
-rule android.nfc.cardemulation.NfcFServiceInfoProto* com.android.nfc.x.@0
-rule android.nfc.NdefMessageProto* com.android.nfc.x.@0
-rule android.nfc.NdefRecordProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.CardEmulationManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.RegisteredServicesCacheProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.RegisteredNfcFServicesCacheProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.PreferredServicesProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.EnabledNfcFServicesProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.RegisteredAidCacheProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.AidRoutingManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.RegisteredT3tIdentifiersCacheProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.SystemCodeRoutingManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.HostEmulationManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.HostNfcFEmulationManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.NfcServiceDumpProto* com.android.nfc.x.@0
-rule com.android.nfc.DiscoveryParamsProto* com.android.nfc.x.@0
-rule com.android.nfc.NfcDispatcherProto* com.android.nfc.x.@0
-rule android.os.PersistableBundleProto* com.android.nfc.x.@0
-
-# Used by framework-nfc for reading trunk stable flags
-rule android.nfc.*Flags* com.android.nfc.x.@0
-rule android.nfc.Flags com.android.nfc.x.@0
-rule android.permission.flags.** com.android.nfc.x.@0
-
-# Used by framework-nfc for misc utilities
-rule android.os.PatternMatcher* com.android.nfc.x.@0
-
-rule com.android.incident.Privacy* com.android.nfc.x.@0
-rule com.android.incident.PrivacyFlags* com.android.nfc.x.@0
diff --git a/nfc/java/android/nfc/ApduList.aidl b/nfc/java/android/nfc/ApduList.aidl
deleted file mode 100644
index f6236b2..0000000
--- a/nfc/java/android/nfc/ApduList.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2011 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 android.nfc;
-
-parcelable ApduList;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/ApduList.java b/nfc/java/android/nfc/ApduList.java
deleted file mode 100644
index 027141d..0000000
--- a/nfc/java/android/nfc/ApduList.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package android.nfc;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @hide
- */
-public class ApduList implements Parcelable {
-
-    private ArrayList<byte[]> commands = new ArrayList<byte[]>();
-
-    public ApduList() {
-    }
-
-    public void add(byte[] command) {
-        commands.add(command);
-    }
-
-    public List<byte[]> get() {
-        return commands;
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<ApduList> CREATOR =
-        new Parcelable.Creator<ApduList>() {
-        @Override
-        public ApduList createFromParcel(Parcel in) {
-            return new ApduList(in);
-        }
-
-        @Override
-        public ApduList[] newArray(int size) {
-            return new ApduList[size];
-        }
-    };
-
-    private ApduList(Parcel in) {
-        int count = in.readInt();
-
-        for (int i = 0 ; i < count ; i++) {
-
-            int length = in.readInt();
-            byte[] cmd = new byte[length];
-            in.readByteArray(cmd);
-            commands.add(cmd);
-        }
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(commands.size());
-
-        for (byte[] cmd : commands) {
-            dest.writeInt(cmd.length);
-            dest.writeByteArray(cmd);
-        }
-    }
-}
-
-
diff --git a/nfc/java/android/nfc/AvailableNfcAntenna.aidl b/nfc/java/android/nfc/AvailableNfcAntenna.aidl
deleted file mode 100644
index 9d06e2d..0000000
--- a/nfc/java/android/nfc/AvailableNfcAntenna.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.nfc;
-
-parcelable AvailableNfcAntenna;
diff --git a/nfc/java/android/nfc/AvailableNfcAntenna.java b/nfc/java/android/nfc/AvailableNfcAntenna.java
deleted file mode 100644
index e76aeb0..0000000
--- a/nfc/java/android/nfc/AvailableNfcAntenna.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Represents a single available Nfc antenna
- * on an Android device.
- */
-public final class AvailableNfcAntenna implements Parcelable {
-    /**
-     * Location of the antenna on the Y axis in millimeters.
-     * 0 is the top-left when the user is facing the screen
-     * and the device orientation is Portrait.
-     */
-    private final int mLocationX;
-    /**
-     * Location of the antenna on the Y axis in millimeters.
-     * 0 is the top-left when the user is facing the screen
-     * and the device orientation is Portrait.
-     */
-    private final int mLocationY;
-
-    public AvailableNfcAntenna(int locationX, int locationY) {
-        this.mLocationX = locationX;
-        this.mLocationY = locationY;
-    }
-
-    /**
-     * Location of the antenna on the X axis in millimeters.
-     * 0 is the top-left when the user is facing the screen
-     * and the device orientation is Portrait.
-     */
-    public int getLocationX() {
-        return mLocationX;
-    }
-
-    /**
-     * Location of the antenna on the Y axis in millimeters.
-     * 0 is the top-left when the user is facing the screen
-     * and the device orientation is Portrait.
-     */
-    public int getLocationY() {
-        return mLocationY;
-    }
-
-    private AvailableNfcAntenna(Parcel in) {
-        this.mLocationX = in.readInt();
-        this.mLocationY = in.readInt();
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<AvailableNfcAntenna>
-            CREATOR = new Parcelable.Creator<AvailableNfcAntenna>() {
-                @Override
-                public AvailableNfcAntenna createFromParcel(Parcel in) {
-                    return new AvailableNfcAntenna(in);
-                }
-
-                @Override
-                public AvailableNfcAntenna[] newArray(int size) {
-                    return new AvailableNfcAntenna[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mLocationX);
-        dest.writeInt(mLocationY);
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + mLocationX;
-        result = prime * result + mLocationY;
-        return result;
-    }
-
-    /**
-     * Returns true if the specified AvailableNfcAntenna contains
-     * identical specifications.
-     */
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        AvailableNfcAntenna other = (AvailableNfcAntenna) obj;
-        if (this.mLocationX != other.mLocationX) return false;
-        return this.mLocationY == other.mLocationY;
-    }
-
-    @Override
-    public String toString() {
-        return "AvailableNfcAntenna " + "x: " + mLocationX + " y: " + mLocationY;
-    }
-}
diff --git a/nfc/java/android/nfc/ComponentNameAndUser.aidl b/nfc/java/android/nfc/ComponentNameAndUser.aidl
deleted file mode 100644
index e677998..0000000
--- a/nfc/java/android/nfc/ComponentNameAndUser.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-parcelable ComponentNameAndUser;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/ComponentNameAndUser.java b/nfc/java/android/nfc/ComponentNameAndUser.java
deleted file mode 100644
index 59e6c62..0000000
--- a/nfc/java/android/nfc/ComponentNameAndUser.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import android.annotation.UserIdInt;
-import android.content.ComponentName;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * @hide
- */
-public class ComponentNameAndUser implements Parcelable {
-    @UserIdInt private final int mUserId;
-    private ComponentName mComponentName;
-
-    public ComponentNameAndUser(@UserIdInt int userId, ComponentName componentName) {
-        mUserId = userId;
-        mComponentName = componentName;
-    }
-
-    /**
-     * @hide
-     */
-    public int describeContents() {
-        return 0;
-    }
-
-    /**
-     * @hide
-     */
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(mUserId);
-        out.writeParcelable(mComponentName, flags);
-    }
-
-    public static final Parcelable.Creator<ComponentNameAndUser> CREATOR =
-            new Parcelable.Creator<ComponentNameAndUser>() {
-                public ComponentNameAndUser createFromParcel(Parcel in) {
-                    return new ComponentNameAndUser(in);
-                }
-
-                public ComponentNameAndUser[] newArray(int size) {
-                    return new ComponentNameAndUser[size];
-                }
-            };
-
-    private ComponentNameAndUser(Parcel in) {
-        mUserId = in.readInt();
-        mComponentName = in.readParcelable(null, ComponentName.class);
-    }
-
-    @UserIdInt
-    public int getUserId() {
-        return mUserId;
-    }
-
-    public ComponentName getComponentName() {
-        return mComponentName;
-    }
-
-    @Override
-    public String toString() {
-        return mComponentName + " for user id: " + mUserId;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj != null && obj instanceof ComponentNameAndUser) {
-            ComponentNameAndUser other = (ComponentNameAndUser) obj;
-            return other.getUserId() == mUserId
-                    && Objects.equals(other.getComponentName(), mComponentName);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (mComponentName == null) {
-            return mUserId;
-        }
-        return mComponentName.hashCode() + mUserId;
-    }
-}
diff --git a/nfc/java/android/nfc/Constants.java b/nfc/java/android/nfc/Constants.java
deleted file mode 100644
index 9b11e2d..0000000
--- a/nfc/java/android/nfc/Constants.java
+++ /dev/null
@@ -1,42 +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 android.nfc;
-
-import android.provider.Settings;
-
-/**
- * @hide
- * TODO(b/303286040): Holds @hide API constants. Formalize these APIs.
- */
-public final class Constants {
-    private Constants() { }
-
-    public static final String SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND = "nfc_payment_foreground";
-    public static final String SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component";
-    public static final String FEATURE_NFC_ANY = "android.hardware.nfc.any";
-
-    /**
-     * @hide constant copied from {@link Settings.Global}
-     * TODO(b/274636414): Migrate to official API in Android V.
-     */
-    public static final String SETTINGS_SATELLITE_MODE_RADIOS = "satellite_mode_radios";
-    /**
-     * @hide constant copied from {@link Settings.Global}
-     * TODO(b/274636414): Migrate to official API in Android V.
-     */
-    public static final String SETTINGS_SATELLITE_MODE_ENABLED = "satellite_mode_enabled";
-}
diff --git a/nfc/java/android/nfc/Entry.aidl b/nfc/java/android/nfc/Entry.aidl
deleted file mode 100644
index 148c4ec..0000000
--- a/nfc/java/android/nfc/Entry.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-parcelable Entry;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/Entry.java b/nfc/java/android/nfc/Entry.java
deleted file mode 100644
index aa5ba58..0000000
--- a/nfc/java/android/nfc/Entry.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-
-/** @hide */
-public final class Entry implements Parcelable {
-    private final byte mType;
-    private final byte mNfceeId;
-    private final String mEntry;
-    private final String mRoutingType;
-
-    public Entry(String entry, byte type, byte nfceeId, String routingType) {
-        mEntry = entry;
-        mType = type;
-        mNfceeId = nfceeId;
-        mRoutingType = routingType;
-    }
-
-    public byte getType() {
-        return mType;
-    }
-
-    public byte getNfceeId() {
-        return mNfceeId;
-    }
-
-    public String getEntry() {
-        return mEntry;
-    }
-
-    public String getRoutingType() {
-        return mRoutingType;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    private Entry(Parcel in) {
-        this.mEntry = in.readString();
-        this.mNfceeId = in.readByte();
-        this.mType = in.readByte();
-        this.mRoutingType = in.readString();
-    }
-
-    public static final @NonNull Parcelable.Creator<Entry> CREATOR =
-            new Parcelable.Creator<Entry>() {
-                @Override
-                public Entry createFromParcel(Parcel in) {
-                    return new Entry(in);
-                }
-
-                @Override
-                public Entry[] newArray(int size) {
-                    return new Entry[size];
-                }
-            };
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeString(mEntry);
-        dest.writeByte(mNfceeId);
-        dest.writeByte(mType);
-        dest.writeString(mRoutingType);
-    }
-}
diff --git a/nfc/java/android/nfc/ErrorCodes.java b/nfc/java/android/nfc/ErrorCodes.java
deleted file mode 100644
index d2c81cd..0000000
--- a/nfc/java/android/nfc/ErrorCodes.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2010, 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 android.nfc;
-
-import android.compat.annotation.UnsupportedAppUsage;
-
-/**
- * This class defines all the error codes that can be returned by the service
- * and producing an exception on the application level. These are needed since
- * binders does not support exceptions.
- *
- * @hide
- */
-public class ErrorCodes {
-
-    @UnsupportedAppUsage
-    public static boolean isError(int code) {
-        if (code < 0) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    public static String asString(int code) {
-        switch (code) {
-            case SUCCESS: return "SUCCESS";
-            case ERROR_IO: return "IO";
-            case ERROR_CANCELLED: return "CANCELLED";
-            case ERROR_TIMEOUT: return "TIMEOUT";
-            case ERROR_BUSY: return "BUSY";
-            case ERROR_CONNECT: return "CONNECT/DISCONNECT";
-//            case ERROR_DISCONNECT: return "DISCONNECT";
-            case ERROR_READ: return "READ";
-            case ERROR_WRITE: return "WRITE";
-            case ERROR_INVALID_PARAM: return "INVALID_PARAM";
-            case ERROR_INSUFFICIENT_RESOURCES: return "INSUFFICIENT_RESOURCES";
-            case ERROR_SOCKET_CREATION: return "SOCKET_CREATION";
-            case ERROR_SOCKET_NOT_CONNECTED: return "SOCKET_NOT_CONNECTED";
-            case ERROR_BUFFER_TO_SMALL: return "BUFFER_TO_SMALL";
-            case ERROR_SAP_USED: return "SAP_USED";
-            case ERROR_SERVICE_NAME_USED: return "SERVICE_NAME_USED";
-            case ERROR_SOCKET_OPTIONS: return "SOCKET_OPTIONS";
-            case ERROR_NFC_ON: return "NFC_ON";
-            case ERROR_NOT_INITIALIZED: return "NOT_INITIALIZED";
-            case ERROR_SE_ALREADY_SELECTED: return "SE_ALREADY_SELECTED";
-            case ERROR_SE_CONNECTED: return "SE_CONNECTED";
-            case ERROR_NO_SE_CONNECTED: return "NO_SE_CONNECTED";
-            case ERROR_NOT_SUPPORTED: return "NOT_SUPPORTED";
-            default: return "UNKNOWN ERROR";
-        }
-    }
-
-    public static final int SUCCESS = 0;
-
-    public static final int ERROR_IO = -1;
-
-    public static final int ERROR_CANCELLED = -2;
-
-    public static final int ERROR_TIMEOUT = -3;
-
-    public static final int ERROR_BUSY = -4;
-
-    public static final int ERROR_CONNECT = -5;
-
-    public static final int ERROR_DISCONNECT = -5;
-
-    public static final int ERROR_READ = -6;
-
-    public static final int ERROR_WRITE = -7;
-
-    public static final int ERROR_INVALID_PARAM = -8;
-
-    public static final int ERROR_INSUFFICIENT_RESOURCES = -9;
-
-    public static final int ERROR_SOCKET_CREATION = -10;
-
-    public static final int ERROR_SOCKET_NOT_CONNECTED = -11;
-
-    public static final int ERROR_BUFFER_TO_SMALL = -12;
-
-    public static final int ERROR_SAP_USED = -13;
-
-    public static final int ERROR_SERVICE_NAME_USED = -14;
-
-    public static final int ERROR_SOCKET_OPTIONS = -15;
-
-    public static final int ERROR_NFC_ON = -16;
-
-    public static final int ERROR_NOT_INITIALIZED = -17;
-
-    public static final int ERROR_SE_ALREADY_SELECTED = -18;
-
-    public static final int ERROR_SE_CONNECTED = -19;
-
-    public static final int ERROR_NO_SE_CONNECTED = -20;
-
-    public static final int ERROR_NOT_SUPPORTED = -21;
-
-}
diff --git a/nfc/java/android/nfc/FormatException.java b/nfc/java/android/nfc/FormatException.java
deleted file mode 100644
index a57de1e..0000000
--- a/nfc/java/android/nfc/FormatException.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2010, 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 android.nfc;
-
-public class FormatException extends Exception {
-    public FormatException() {
-        super();
-    }
-
-    public FormatException(String message) {
-        super(message);
-    }
-
-    public FormatException(String message, Throwable e) {
-        super(message, e);
-    }
-}
diff --git a/nfc/java/android/nfc/IAppCallback.aidl b/nfc/java/android/nfc/IAppCallback.aidl
deleted file mode 100644
index b06bf06..0000000
--- a/nfc/java/android/nfc/IAppCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2011 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 android.nfc;
-
-import android.nfc.Tag;
-
-/**
- * @hide
- */
-interface IAppCallback
-{
-    oneway void onTagDiscovered(in Tag tag);
-}
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
deleted file mode 100644
index ac0a5aa..0000000
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc;
-
-import android.app.PendingIntent;
-import android.content.IntentFilter;
-import android.nfc.Entry;
-import android.nfc.NdefMessage;
-import android.nfc.Tag;
-import android.nfc.TechListParcel;
-import android.nfc.IAppCallback;
-import android.nfc.INfcAdapterExtras;
-import android.nfc.INfcControllerAlwaysOnListener;
-import android.nfc.INfcVendorNciCallback;
-import android.nfc.INfcTag;
-import android.nfc.INfcCardEmulation;
-import android.nfc.INfcFCardEmulation;
-import android.nfc.INfcOemExtensionCallback;
-import android.nfc.INfcUnlockHandler;
-import android.nfc.IT4tNdefNfcee;
-import android.nfc.ITagRemovedCallback;
-import android.nfc.INfcDta;
-import android.nfc.INfcWlcStateListener;
-import android.nfc.NfcAntennaInfo;
-import android.nfc.WlcListenerDeviceInfo;
-import android.nfc.cardemulation.PollingFrame;
-import android.os.Bundle;
-
-/**
- * @hide
- */
-interface INfcAdapter
-{
-    INfcTag getNfcTagInterface();
-    INfcCardEmulation getNfcCardEmulationInterface();
-    INfcFCardEmulation getNfcFCardEmulationInterface();
-    INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg);
-    INfcDta getNfcDtaInterface(in String pkg);
-    int getState();
-    boolean disable(boolean saveState, in String pkg);
-    boolean enable(in String pkg);
-    int pausePolling(long timeoutInMs);
-    int resumePolling();
-
-    void setForegroundDispatch(in PendingIntent intent,
-            in IntentFilter[] filters, in TechListParcel techLists);
-    void setAppCallback(in IAppCallback callback);
-
-    boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback);
-
-    void dispatch(in Tag tag);
-
-    void setReaderMode (IBinder b, IAppCallback callback, int flags, in Bundle extras, String pkg);
-
-    void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, in int[] techList);
-    void removeNfcUnlockHandler(INfcUnlockHandler unlockHandler);
-
-    void verifyNfcPermission();
-    boolean isNfcSecureEnabled();
-    boolean deviceSupportsNfcSecure();
-    boolean setNfcSecure(boolean enable);
-    NfcAntennaInfo getNfcAntennaInfo();
-
-    void setControllerAlwaysOn(int mode);
-    boolean isControllerAlwaysOn();
-    boolean isControllerAlwaysOnSupported();
-    void registerControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener);
-    void unregisterControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener);
-    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
-    boolean isTagIntentAppPreferenceSupported();
-    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
-    Map getTagIntentAppPreferenceForUser(int userId);
-    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
-    int setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow);
-
-    boolean isReaderOptionEnabled();
-    boolean isReaderOptionSupported();
-    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
-    boolean enableReaderOption(boolean enable, in String pkg);
-    boolean isObserveModeSupported();
-    boolean isObserveModeEnabled();
-    boolean setObserveMode(boolean enabled, String pkg);
-
-    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
-    boolean setWlcEnabled(boolean enable);
-    boolean isWlcEnabled();
-    void registerWlcStateListener(in INfcWlcStateListener listener);
-    void unregisterWlcStateListener(in INfcWlcStateListener listener);
-    WlcListenerDeviceInfo getWlcListenerDeviceInfo();
-
-    void updateDiscoveryTechnology(IBinder b, int pollFlags, int listenFlags, String pkg);
-
-    void notifyPollingLoop(in PollingFrame frame);
-    void notifyHceDeactivated();
-    void notifyTestHceData(in int technology, in byte[] data);
-    int sendVendorNciMessage(int mt, int gid, int oid, in byte[] payload);
-    void registerVendorExtensionCallback(in INfcVendorNciCallback callbacks);
-    void unregisterVendorExtensionCallback(in INfcVendorNciCallback callbacks);
-    void registerOemExtensionCallback(INfcOemExtensionCallback callbacks);
-    void unregisterOemExtensionCallback(INfcOemExtensionCallback callbacks);
-    void clearPreference();
-    void setScreenState();
-    void checkFirmware();
-    Map fetchActiveNfceeList();
-    void triggerInitialization();
-    boolean getSettingStatus();
-    boolean isTagPresent();
-    List<Entry> getRoutingTableEntryList();
-    void indicateDataMigration(boolean inProgress, String pkg);
-    int commitRouting();
-    boolean isTagIntentAllowed(in String pkg, in int Userid);
-    IT4tNdefNfcee getT4tNdefNfceeInterface();
-    long getMaxPausePollingTimeoutMs();
-}
diff --git a/nfc/java/android/nfc/INfcAdapterExtras.aidl b/nfc/java/android/nfc/INfcAdapterExtras.aidl
deleted file mode 100644
index cde57c5..0000000
--- a/nfc/java/android/nfc/INfcAdapterExtras.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2011 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 android.nfc;
-
-import android.os.Bundle;
-
-
-/**
- * {@hide}
- */
-interface INfcAdapterExtras {
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    Bundle open(in String pkg, IBinder b);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    Bundle close(in String pkg, IBinder b);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    Bundle transceive(in String pkg, in byte[] data_in);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    int getCardEmulationRoute(in String pkg);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    void setCardEmulationRoute(in String pkg, int route);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    void authenticate(in String pkg, in byte[] token);
-    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
-    String getDriverName(in String pkg);
-}
diff --git a/nfc/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl
deleted file mode 100644
index 00ceaa9..0000000
--- a/nfc/java/android/nfc/INfcCardEmulation.aidl
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.nfc;
-
-import android.content.ComponentName;
-import android.nfc.INfcEventCallback;
-
-import android.nfc.cardemulation.AidGroup;
-import android.nfc.cardemulation.ApduServiceInfo;
-import android.os.RemoteCallback;
-
-/**
- * @hide
- */
-interface INfcCardEmulation
-{
-    boolean isDefaultServiceForCategory(int userHandle, in ComponentName service, String category);
-    boolean isDefaultServiceForAid(int userHandle, in ComponentName service, String aid);
-    boolean setDefaultServiceForCategory(int userHandle, in ComponentName service, String category);
-    boolean setDefaultForNextTap(int userHandle, in ComponentName service);
-    boolean setShouldDefaultToObserveModeForService(int userId, in android.content.ComponentName service, boolean enable);
-    boolean registerAidGroupForService(int userHandle, in ComponentName service, in AidGroup aidGroup);
-    boolean registerPollingLoopFilterForService(int userHandle, in ComponentName service, in String pollingLoopFilter, boolean autoTransact);
-    boolean registerPollingLoopPatternFilterForService(int userHandle, in ComponentName service, in String pollingLoopPatternFilter, boolean autoTransact);
-    boolean setOffHostForService(int userHandle, in ComponentName service, in String offHostSecureElement);
-    boolean unsetOffHostForService(int userHandle, in ComponentName service);
-    AidGroup getAidGroupForService(int userHandle, in ComponentName service, String category);
-    boolean removeAidGroupForService(int userHandle, in ComponentName service, String category);
-    boolean removePollingLoopFilterForService(int userHandle, in ComponentName service, in String pollingLoopFilter);
-    boolean removePollingLoopPatternFilterForService(int userHandle, in ComponentName service, in String pollingLoopPatternFilter);
-    List<ApduServiceInfo> getServices(int userHandle, in String category);
-    boolean setPreferredService(in ComponentName service);
-    boolean unsetPreferredService();
-    boolean supportsAidPrefixRegistration();
-    ApduServiceInfo getPreferredPaymentService(int userHandle);
-    int setServiceEnabledForCategoryOther(int userHandle, in ComponentName app, boolean status);
-    boolean isDefaultPaymentRegistered();
-
-    void overrideRoutingTable(int userHandle, String protocol, String technology, in String pkg);
-    void recoverRoutingTable(int userHandle);
-    boolean isEuiccSupported();
-    int getDefaultNfcSubscriptionId(in String pkg);
-    int setDefaultNfcSubscriptionId(int subscriptionId, in String pkg);
-    void setAutoChangeStatus(boolean state);
-    boolean isAutoChangeEnabled();
-    List<String> getRoutingStatus();
-    void overwriteRoutingTable(int userHandle, String emptyAid, String protocol, String tech, String sc);
-
-    void registerNfcEventCallback(in INfcEventCallback listener);
-    void unregisterNfcEventCallback(in INfcEventCallback listener);
-}
diff --git a/nfc/java/android/nfc/INfcControllerAlwaysOnListener.aidl b/nfc/java/android/nfc/INfcControllerAlwaysOnListener.aidl
deleted file mode 100644
index 1bb7680..0000000
--- a/nfc/java/android/nfc/INfcControllerAlwaysOnListener.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-/**
- * @hide
- */
-oneway interface INfcControllerAlwaysOnListener {
-  /**
-   * Called whenever the controller always on state changes
-   *
-   * @param isEnabled true if the state is enabled, false otherwise
-   */
-  void onControllerAlwaysOnChanged(boolean isEnabled);
-}
diff --git a/nfc/java/android/nfc/INfcDta.aidl b/nfc/java/android/nfc/INfcDta.aidl
deleted file mode 100644
index 4cc5927..0000000
--- a/nfc/java/android/nfc/INfcDta.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
- /*
-  * Copyright (C) 2017 NXP Semiconductors
-  *
-  * 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 android.nfc;
-
-import android.os.Bundle;
-
-/**
- * {@hide}
- */
-interface INfcDta {
-
-    void enableDta();
-    void disableDta();
-    boolean enableServer(String serviceName, int serviceSap, int miu,
-            int rwSize,int testCaseId);
-    void disableServer();
-    boolean enableClient(String serviceName, int miu, int rwSize,
-            int testCaseId);
-    void disableClient();
-    boolean registerMessageService(String msgServiceName);
-}
diff --git a/nfc/java/android/nfc/INfcEventCallback.aidl b/nfc/java/android/nfc/INfcEventCallback.aidl
deleted file mode 100644
index af1fa2fb..0000000
--- a/nfc/java/android/nfc/INfcEventCallback.aidl
+++ /dev/null
@@ -1,16 +0,0 @@
-package android.nfc;
-
-import android.nfc.ComponentNameAndUser;
-
-/**
- * @hide
- */
-oneway interface INfcEventCallback {
-    void onPreferredServiceChanged(in ComponentNameAndUser ComponentNameAndUser);
-    void onObserveModeStateChanged(boolean isEnabled);
-    void onAidConflictOccurred(in String aid);
-    void onAidNotRouted(in String aid);
-    void onNfcStateChanged(in int nfcState);
-    void onRemoteFieldChanged(boolean isDetected);
-    void onInternalErrorReported(in int errorType);
-}
\ No newline at end of file
diff --git a/nfc/java/android/nfc/INfcFCardEmulation.aidl b/nfc/java/android/nfc/INfcFCardEmulation.aidl
deleted file mode 100644
index 124bfac..0000000
--- a/nfc/java/android/nfc/INfcFCardEmulation.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.content.ComponentName;
-import android.nfc.cardemulation.NfcFServiceInfo;
-
-/**
- * @hide
- */
-interface INfcFCardEmulation
-{
-    String getSystemCodeForService(int userHandle, in ComponentName service);
-    boolean registerSystemCodeForService(int userHandle, in ComponentName service, String systemCode);
-    boolean removeSystemCodeForService(int userHandle, in ComponentName service);
-    String getNfcid2ForService(int userHandle, in ComponentName service);
-    boolean setNfcid2ForService(int userHandle, in ComponentName service, String nfcid2);
-    boolean enableNfcFForegroundService(in ComponentName service);
-    boolean disableNfcFForegroundService();
-    List<NfcFServiceInfo> getNfcFServices(int userHandle);
-    int getMaxNumOfRegisterableSystemCodes();
-}
diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
deleted file mode 100644
index 357d322..0000000
--- a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2024 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 android.nfc;
-
-import android.content.ComponentName;
-import android.nfc.cardemulation.ApduServiceInfo;
-import android.nfc.NdefMessage;
-import android.nfc.OemLogItems;
-import android.nfc.Tag;
-import android.os.ResultReceiver;
-
-import java.util.List;
-
-/**
- * @hide
- */
-interface INfcOemExtensionCallback {
-   void onTagConnected(boolean connected);
-   void onStateUpdated(int state);
-   void onApplyRouting(in ResultReceiver isSkipped);
-   void onNdefRead(in ResultReceiver isSkipped);
-   void onEnable(in ResultReceiver isAllowed);
-   void onDisable(in ResultReceiver isAllowed);
-   void onBootStarted();
-   void onEnableStarted();
-   void onDisableStarted();
-   void onBootFinished(int status);
-   void onEnableFinished(int status);
-   void onDisableFinished(int status);
-   void onTagDispatch(in ResultReceiver isSkipped);
-   void onRoutingChanged(in ResultReceiver isSkipped);
-   void onHceEventReceived(int action);
-   void onReaderOptionChanged(boolean enabled);
-   void onCardEmulationActivated(boolean isActivated);
-   void onRfFieldDetected(boolean isActive);
-   void onRfDiscoveryStarted(boolean isDiscoveryStarted);
-   void onEeListenActivated(boolean isActivated);
-   void onEeUpdated();
-   void onGetOemAppSearchIntent(in List<String> firstPackage, in ResultReceiver intentConsumer);
-   void onNdefMessage(in Tag tag, in NdefMessage message, in ResultReceiver hasOemExecutableContent);
-   void onLaunchHceAppChooserActivity(in String selectedAid, in List<ApduServiceInfo> services, in ComponentName failedComponent, in String category);
-   void onLaunchHceTapAgainActivity(in ApduServiceInfo service, in String category);
-   void onRoutingTableFull();
-   void onLogEventNotified(in OemLogItems item);
-   void onExtractOemPackages(in NdefMessage message, in ResultReceiver packageReceiver);
-}
diff --git a/nfc/java/android/nfc/INfcTag.aidl b/nfc/java/android/nfc/INfcTag.aidl
deleted file mode 100644
index 170df71..0000000
--- a/nfc/java/android/nfc/INfcTag.aidl
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc;
-
-import android.nfc.NdefMessage;
-import android.nfc.Tag;
-import android.nfc.TransceiveResult;
-
-/**
- * @hide
- */
-interface INfcTag
-{
-    int connect(int nativeHandle, int technology);
-    int reconnect(int nativeHandle);
-    int[] getTechList(int nativeHandle);
-    boolean isNdef(int nativeHandle);
-    boolean isPresent(int nativeHandle);
-    TransceiveResult transceive(int nativeHandle, in byte[] data, boolean raw);
-
-    NdefMessage ndefRead(int nativeHandle);
-    int ndefWrite(int nativeHandle, in NdefMessage msg);
-    int ndefMakeReadOnly(int nativeHandle);
-    boolean ndefIsWritable(int nativeHandle);
-    int formatNdef(int nativeHandle, in byte[] key);
-    Tag rediscover(int nativehandle);
-
-    int setTimeout(int technology, int timeout);
-    int getTimeout(int technology);
-    void resetTimeouts();
-    boolean canMakeReadOnly(int ndefType);
-    int getMaxTransceiveLength(int technology);
-    boolean getExtendedLengthApdusSupported();
-
-    boolean isTagUpToDate(long cookie);
-}
diff --git a/nfc/java/android/nfc/INfcUnlockHandler.aidl b/nfc/java/android/nfc/INfcUnlockHandler.aidl
deleted file mode 100644
index e1cace9..0000000
--- a/nfc/java/android/nfc/INfcUnlockHandler.aidl
+++ /dev/null
@@ -1,12 +0,0 @@
-package android.nfc;
-
-import android.nfc.Tag;
-
-/**
- * @hide
- */
-interface INfcUnlockHandler {
-
-    boolean onUnlockAttempted(in Tag tag);
-
-}
diff --git a/nfc/java/android/nfc/INfcVendorNciCallback.aidl b/nfc/java/android/nfc/INfcVendorNciCallback.aidl
deleted file mode 100644
index 821dc6f..0000000
--- a/nfc/java/android/nfc/INfcVendorNciCallback.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-/**
- * @hide
- */
-oneway interface INfcVendorNciCallback {
-    void onVendorResponseReceived(int gid, int oid, in byte[] payload);
-    void onVendorNotificationReceived(int gid, int oid, in byte[] payload);
-}
diff --git a/nfc/java/android/nfc/INfcWlcStateListener.aidl b/nfc/java/android/nfc/INfcWlcStateListener.aidl
deleted file mode 100644
index 584eb9a..0000000
--- a/nfc/java/android/nfc/INfcWlcStateListener.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 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 android.nfc;
-
-import android.nfc.WlcListenerDeviceInfo;
-/**
- * @hide
- */
-oneway interface INfcWlcStateListener {
-  /**
-   * Called whenever NFC WLC state changes
-   *
-   * @param wlcListenerDeviceInfo NFC wlc listener information
-   */
-  void onWlcStateChanged(in WlcListenerDeviceInfo wlcListenerDeviceInfo);
-}
diff --git a/nfc/java/android/nfc/IT4tNdefNfcee.aidl b/nfc/java/android/nfc/IT4tNdefNfcee.aidl
deleted file mode 100644
index b4cda5b..0000000
--- a/nfc/java/android/nfc/IT4tNdefNfcee.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/******************************************************************************
- *
- *  Copyright (C) 2024 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 android.nfc;
-
-import android.nfc.T4tNdefNfceeCcFileInfo;
-
-/**
- * @hide
- */
-interface IT4tNdefNfcee {
-    int writeData(in int fileId, in byte[] data);
-    byte[] readData(in int fileId);
-    int clearNdefData();
-    boolean isNdefOperationOngoing();
-    boolean isNdefNfceeEmulationSupported();
-    T4tNdefNfceeCcFileInfo readCcfile();
-}
diff --git a/nfc/java/android/nfc/ITagRemovedCallback.aidl b/nfc/java/android/nfc/ITagRemovedCallback.aidl
deleted file mode 100644
index 2a06ff3..0000000
--- a/nfc/java/android/nfc/ITagRemovedCallback.aidl
+++ /dev/null
@@ -1,8 +0,0 @@
-package android.nfc;
-
-/**
- * @hide
- */
-oneway interface ITagRemovedCallback {
-    void onTagRemoved();
-}
diff --git a/nfc/java/android/nfc/NdefMessage.aidl b/nfc/java/android/nfc/NdefMessage.aidl
deleted file mode 100644
index 378b9d0..0000000
--- a/nfc/java/android/nfc/NdefMessage.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc;
-
-parcelable NdefMessage;
diff --git a/nfc/java/android/nfc/NdefMessage.java b/nfc/java/android/nfc/NdefMessage.java
deleted file mode 100644
index 553f6c0..0000000
--- a/nfc/java/android/nfc/NdefMessage.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc;
-
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.proto.ProtoOutputStream;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-/**
- * Represents an immutable NDEF Message.
- * <p>
- * NDEF (NFC Data Exchange Format) is a light-weight binary format,
- * used to encapsulate typed data. It is specified by the NFC Forum,
- * for transmission and storage with NFC, however it is transport agnostic.
- * <p>
- * NDEF defines messages and records. An NDEF Record contains
- * typed data, such as MIME-type media, a URI, or a custom
- * application payload. An NDEF Message is a container for
- * one or more NDEF Records.
- * <p>
- * When an Android device receives an NDEF Message
- * (for example by reading an NFC tag) it processes it through
- * a dispatch mechanism to determine an activity to launch.
- * The type of the <em>first</em> record in the message has
- * special importance for message dispatch, so design this record
- * carefully.
- * <p>
- * Use {@link #NdefMessage(byte[])} to construct an NDEF Message from
- * binary data, or {@link #NdefMessage(NdefRecord[])} to
- * construct from one or more {@link NdefRecord}s.
- * <p class="note">
- * {@link NdefMessage} and {@link NdefRecord} implementations are
- * always available, even on Android devices that do not have NFC hardware.
- * <p class="note">
- * {@link NdefRecord}s are intended to be immutable (and thread-safe),
- * however they may contain mutable fields. So take care not to modify
- * mutable fields passed into constructors, or modify mutable fields
- * obtained by getter methods, unless such modification is explicitly
- * marked as safe.
- *
- * @see NfcAdapter#ACTION_NDEF_DISCOVERED
- * @see NdefRecord
- */
-public final class NdefMessage implements Parcelable {
-    private final NdefRecord[] mRecords;
-
-    /**
-     * Construct an NDEF Message by parsing raw bytes.<p>
-     * Strict validation of the NDEF binary structure is performed:
-     * there must be at least one record, every record flag must
-     * be correct, and the total length of the message must match
-     * the length of the input data.<p>
-     * This parser can handle chunked records, and converts them
-     * into logical {@link NdefRecord}s within the message.<p>
-     * Once the input data has been parsed to one or more logical
-     * records, basic validation of the tnf, type, id, and payload fields
-     * of each record is performed, as per the documentation on
-     * on {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])}<p>
-     * If either strict validation of the binary format fails, or
-     * basic validation during record construction fails, a
-     * {@link FormatException} is thrown<p>
-     * Deep inspection of the type, id and payload fields of
-     * each record is not performed, so it is possible to parse input
-     * that has a valid binary format and confirms to the basic
-     * validation requirements of
-     * {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])},
-     * but fails more strict requirements as specified by the
-     * NFC Forum.
-     *
-     * <p class="note">
-     * It is safe to re-use the data byte array after construction:
-     * this constructor will make an internal copy of all necessary fields.
-     *
-     * @param data raw bytes to parse
-     * @throws FormatException if the data cannot be parsed
-     */
-    public NdefMessage(byte[] data) throws FormatException {
-        if (data == null) throw new NullPointerException("data is null");
-        ByteBuffer buffer = ByteBuffer.wrap(data);
-
-        mRecords = NdefRecord.parse(buffer, false);
-
-        if (buffer.remaining() > 0) {
-            throw new FormatException("trailing data");
-        }
-    }
-
-    /**
-     * Construct an NDEF Message from one or more NDEF Records.
-     *
-     * @param record first record (mandatory)
-     * @param records additional records (optional)
-     */
-    public NdefMessage(NdefRecord record, NdefRecord ... records) {
-        // validate
-        if (record == null) throw new NullPointerException("record cannot be null");
-
-        for (NdefRecord r : records) {
-            if (r == null) {
-                throw new NullPointerException("record cannot be null");
-            }
-        }
-
-        mRecords = new NdefRecord[1 + records.length];
-        mRecords[0] = record;
-        System.arraycopy(records, 0, mRecords, 1, records.length);
-    }
-
-    /**
-     * Construct an NDEF Message from one or more NDEF Records.
-     *
-     * @param records one or more records
-     */
-    public NdefMessage(NdefRecord[] records) {
-        // validate
-        if (records.length < 1) {
-            throw new IllegalArgumentException("must have at least one record");
-        }
-        for (NdefRecord r : records) {
-            if (r == null) {
-                throw new NullPointerException("records cannot contain null");
-            }
-        }
-
-        mRecords = records;
-    }
-
-    /**
-     * Get the NDEF Records inside this NDEF Message.<p>
-     * An {@link NdefMessage} always has one or more NDEF Records: so the
-     * following code to retrieve the first record is always safe
-     * (no need to check for null or array length >= 1):
-     * <pre>
-     * NdefRecord firstRecord = ndefMessage.getRecords()[0];
-     * </pre>
-     *
-     * @return array of one or more NDEF records.
-     */
-    public NdefRecord[] getRecords() {
-        return mRecords;
-    }
-
-    /**
-     * Return the length of this NDEF Message if it is written to a byte array
-     * with {@link #toByteArray}.<p>
-     * An NDEF Message can be formatted to bytes in different ways
-     * depending on chunking, SR, and ID flags, so the length returned
-     * by this method may not be equal to the length of the original
-     * byte array used to construct this NDEF Message. However it will
-     * always be equal to the length of the byte array produced by
-     * {@link #toByteArray}.
-     *
-     * @return length of this NDEF Message when written to bytes with {@link #toByteArray}
-     * @see #toByteArray
-     */
-    public int getByteArrayLength() {
-        int length = 0;
-        for (NdefRecord r : mRecords) {
-            length += r.getByteLength();
-        }
-        return length;
-    }
-
-    /**
-     * Return this NDEF Message as raw bytes.<p>
-     * The NDEF Message is formatted as per the NDEF 1.0 specification,
-     * and the byte array is suitable for network transmission or storage
-     * in an NFC Forum NDEF compatible tag.<p>
-     * This method will not chunk any records, and will always use the
-     * short record (SR) format and omit the identifier field when possible.
-     *
-     * @return NDEF Message in binary format
-     * @see #getByteArrayLength()
-     */
-    public byte[] toByteArray() {
-        int length = getByteArrayLength();
-        ByteBuffer buffer = ByteBuffer.allocate(length);
-
-        for (int i=0; i<mRecords.length; i++) {
-            boolean mb = (i == 0);  // first record
-            boolean me = (i == mRecords.length - 1);  // last record
-            mRecords[i].writeToByteBuffer(buffer, mb, me);
-        }
-
-        return buffer.array();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mRecords.length);
-        dest.writeTypedArray(mRecords, flags);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<NdefMessage> CREATOR =
-            new Parcelable.Creator<NdefMessage>() {
-        @Override
-        public NdefMessage createFromParcel(Parcel in) {
-            int recordsLength = in.readInt();
-            NdefRecord[] records = new NdefRecord[recordsLength];
-            in.readTypedArray(records, NdefRecord.CREATOR);
-            return new NdefMessage(records);
-        }
-        @Override
-        public NdefMessage[] newArray(int size) {
-            return new NdefMessage[size];
-        }
-    };
-
-    @Override
-    public int hashCode() {
-        return Arrays.hashCode(mRecords);
-    }
-
-    /**
-     * Returns true if the specified NDEF Message contains
-     * identical NDEF Records.
-     */
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        NdefMessage other = (NdefMessage) obj;
-        return Arrays.equals(mRecords, other.mRecords);
-    }
-
-    @Override
-    public String toString() {
-        return "NdefMessage " + Arrays.toString(mRecords);
-    }
-
-    /**
-     * Dump debugging information as a NdefMessageProto
-     * @hide
-     *
-     * Note:
-     * See proto definition in frameworks/base/core/proto/android/nfc/ndef.proto
-     * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
-     * {@link ProtoOutputStream#end(long)} after.
-     * Never reuse a proto field number. When removing a field, mark it as reserved.
-     */
-    public void dumpDebug(ProtoOutputStream proto) {
-        for (NdefRecord record : mRecords) {
-            long token = proto.start(NdefMessageProto.NDEF_RECORDS);
-            record.dumpDebug(proto);
-            proto.end(token);
-        }
-    }
-}
\ No newline at end of file
diff --git a/nfc/java/android/nfc/NdefRecord.aidl b/nfc/java/android/nfc/NdefRecord.aidl
deleted file mode 100644
index 10f89d0..0000000
--- a/nfc/java/android/nfc/NdefRecord.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc;
-
-parcelable NdefRecord;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/NdefRecord.java b/nfc/java/android/nfc/NdefRecord.java
deleted file mode 100644
index 7bf4355..0000000
--- a/nfc/java/android/nfc/NdefRecord.java
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc;
-
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.proto.ProtoOutputStream;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Represents an immutable NDEF Record.
- * <p>
- * NDEF (NFC Data Exchange Format) is a light-weight binary format,
- * used to encapsulate typed data. It is specified by the NFC Forum,
- * for transmission and storage with NFC, however it is transport agnostic.
- * <p>
- * NDEF defines messages and records. An NDEF Record contains
- * typed data, such as MIME-type media, a URI, or a custom
- * application payload. An NDEF Message is a container for
- * one or more NDEF Records.
- * <p>
- * This class represents logical (complete) NDEF Records, and can not be
- * used to represent chunked (partial) NDEF Records. However
- * {@link NdefMessage#NdefMessage(byte[])} can be used to parse a message
- * containing chunked records, and will return a message with unchunked
- * (complete) records.
- * <p>
- * A logical NDEF Record always contains a 3-bit TNF (Type Name Field)
- * that provides high level typing for the rest of the record. The
- * remaining fields are variable length and not always present:
- * <ul>
- * <li><em>type</em>: detailed typing for the payload</li>
- * <li><em>id</em>: identifier meta-data, not commonly used</li>
- * <li><em>payload</em>: the actual payload</li>
- * </ul>
- * <p>
- * Helpers such as {@link NdefRecord#createUri}, {@link NdefRecord#createMime}
- * and {@link NdefRecord#createExternal} are included to create well-formatted
- * NDEF Records with correctly set tnf, type, id and payload fields, please
- * use these helpers whenever possible.
- * <p>
- * Use the constructor {@link #NdefRecord(short, byte[], byte[], byte[])}
- * if you know what you are doing and what to set the fields individually.
- * Only basic validation is performed with this constructor, so it is possible
- * to create records that do not confirm to the strict NFC Forum
- * specifications.
- * <p>
- * The binary representation of an NDEF Record includes additional flags to
- * indicate location with an NDEF message, provide support for chunking of
- * NDEF records, and to pack optional fields. This class does not expose
- * those details. To write an NDEF Record as binary you must first put it
- * into an {@link NdefMessage}, then call {@link NdefMessage#toByteArray()}.
- * <p class="note">
- * {@link NdefMessage} and {@link NdefRecord} implementations are
- * always available, even on Android devices that do not have NFC hardware.
- * <p class="note">
- * {@link NdefRecord}s are intended to be immutable (and thread-safe),
- * however they may contain mutable fields. So take care not to modify
- * mutable fields passed into constructors, or modify mutable fields
- * obtained by getter methods, unless such modification is explicitly
- * marked as safe.
- *
- * @see NfcAdapter#ACTION_NDEF_DISCOVERED
- * @see NdefMessage
- */
-public final class NdefRecord implements Parcelable {
-    /**
-     * Indicates the record is empty.<p>
-     * Type, id and payload fields are empty in a {@literal TNF_EMPTY} record.
-     */
-    public static final short TNF_EMPTY = 0x00;
-
-    /**
-     * Indicates the type field contains a well-known RTD type name.<p>
-     * Use this tnf with RTD types such as {@link #RTD_TEXT}, {@link #RTD_URI}.
-     * <p>
-     * The RTD type name format is specified in NFCForum-TS-RTD_1.0.
-     *
-     * @see #RTD_URI
-     * @see #RTD_TEXT
-     * @see #RTD_SMART_POSTER
-     * @see #createUri
-     */
-    public static final short TNF_WELL_KNOWN = 0x01;
-
-    /**
-     * Indicates the type field contains a media-type BNF
-     * construct, defined by RFC 2046.<p>
-     * Use this with MIME type names such as {@literal "image/jpeg"}, or
-     * using the helper {@link #createMime}.
-     *
-     * @see #createMime
-     */
-    public static final short TNF_MIME_MEDIA = 0x02;
-
-    /**
-     * Indicates the type field contains an absolute-URI
-     * BNF construct defined by RFC 3986.<p>
-     * When creating new records prefer {@link #createUri},
-     * since it offers more compact URI encoding
-     * ({@literal #RTD_URI} allows compression of common URI prefixes).
-     *
-     * @see #createUri
-     */
-    public static final short TNF_ABSOLUTE_URI = 0x03;
-
-    /**
-     * Indicates the type field contains an external type name.<p>
-     * Used to encode custom payloads. When creating new records
-     * use the helper {@link #createExternal}.<p>
-     * The external-type RTD format is specified in NFCForum-TS-RTD_1.0.<p>
-     * <p>
-     * Note this TNF should not be used with RTD_TEXT or RTD_URI constants.
-     * Those are well known RTD constants, not external RTD constants.
-     *
-     * @see #createExternal
-     */
-    public static final short TNF_EXTERNAL_TYPE = 0x04;
-
-    /**
-     * Indicates the payload type is unknown.<p>
-     * NFC Forum explains this should be treated similarly to the
-     * "application/octet-stream" MIME type. The payload
-     * type is not explicitly encoded within the record.
-     * <p>
-     * The type field is empty in an {@literal TNF_UNKNOWN} record.
-     */
-    public static final short TNF_UNKNOWN = 0x05;
-
-    /**
-     * Indicates the payload is an intermediate or final chunk of a chunked
-     * NDEF Record.<p>
-     * {@literal TNF_UNCHANGED} can not be used with this class
-     * since all {@link NdefRecord}s are already unchunked, however they
-     * may appear in the binary format.
-     */
-    public static final short TNF_UNCHANGED = 0x06;
-
-    /**
-     * Reserved TNF type.
-     * <p>
-     * The NFC Forum NDEF Specification v1.0 suggests for NDEF parsers to treat this
-     * value like TNF_UNKNOWN.
-     * @hide
-     */
-    public static final short TNF_RESERVED = 0x07;
-
-    /**
-     * RTD Text type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_TEXT = {0x54};  // "T"
-
-    /**
-     * RTD URI type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_URI = {0x55};   // "U"
-
-    /**
-     * RTD Smart Poster type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_SMART_POSTER = {0x53, 0x70};  // "Sp"
-
-    /**
-     * RTD Alternative Carrier type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_ALTERNATIVE_CARRIER = {0x61, 0x63};  // "ac"
-
-    /**
-     * RTD Handover Carrier type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_HANDOVER_CARRIER = {0x48, 0x63};  // "Hc"
-
-    /**
-     * RTD Handover Request type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_HANDOVER_REQUEST = {0x48, 0x72};  // "Hr"
-
-    /**
-     * RTD Handover Select type. For use with {@literal TNF_WELL_KNOWN}.
-     * @see #TNF_WELL_KNOWN
-     */
-    public static final byte[] RTD_HANDOVER_SELECT = {0x48, 0x73}; // "Hs"
-
-    /**
-     * RTD Android app type. For use with {@literal TNF_EXTERNAL}.
-     * <p>
-     * The payload of a record with type RTD_ANDROID_APP
-     * should be the package name identifying an application.
-     * Multiple RTD_ANDROID_APP records may be included
-     * in a single {@link NdefMessage}.
-     * <p>
-     * Use {@link #createApplicationRecord(String)} to create
-     * RTD_ANDROID_APP records.
-     * @hide
-     */
-    public static final byte[] RTD_ANDROID_APP = "android.com:pkg".getBytes();
-
-    private static final byte FLAG_MB = (byte) 0x80;
-    private static final byte FLAG_ME = (byte) 0x40;
-    private static final byte FLAG_CF = (byte) 0x20;
-    private static final byte FLAG_SR = (byte) 0x10;
-    private static final byte FLAG_IL = (byte) 0x08;
-
-    /**
-     * NFC Forum "URI Record Type Definition"<p>
-     * This is a mapping of "URI Identifier Codes" to URI string prefixes,
-     * per section 3.2.2 of the NFC Forum URI Record Type Definition document.
-     */
-    private static final String[] URI_PREFIX_MAP = new String[] {
-            "", // 0x00
-            "http://www.", // 0x01
-            "https://www.", // 0x02
-            "http://", // 0x03
-            "https://", // 0x04
-            "tel:", // 0x05
-            "mailto:", // 0x06
-            "ftp://anonymous:anonymous@", // 0x07
-            "ftp://ftp.", // 0x08
-            "ftps://", // 0x09
-            "sftp://", // 0x0A
-            "smb://", // 0x0B
-            "nfs://", // 0x0C
-            "ftp://", // 0x0D
-            "dav://", // 0x0E
-            "news:", // 0x0F
-            "telnet://", // 0x10
-            "imap:", // 0x11
-            "rtsp://", // 0x12
-            "urn:", // 0x13
-            "pop:", // 0x14
-            "sip:", // 0x15
-            "sips:", // 0x16
-            "tftp:", // 0x17
-            "btspp://", // 0x18
-            "btl2cap://", // 0x19
-            "btgoep://", // 0x1A
-            "tcpobex://", // 0x1B
-            "irdaobex://", // 0x1C
-            "file://", // 0x1D
-            "urn:epc:id:", // 0x1E
-            "urn:epc:tag:", // 0x1F
-            "urn:epc:pat:", // 0x20
-            "urn:epc:raw:", // 0x21
-            "urn:epc:", // 0x22
-            "urn:nfc:", // 0x23
-    };
-
-    private static final int MAX_PAYLOAD_SIZE = 10 * (1 << 20);  // 10 MB payload limit
-
-    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
-
-    private final short mTnf;
-    private final byte[] mType;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private final byte[] mId;
-    private final byte[] mPayload;
-
-    /**
-     * Create a new Android Application Record (AAR).
-     * <p>
-     * This record indicates to other Android devices the package
-     * that should be used to handle the entire NDEF message.
-     * You can embed this record anywhere into your message
-     * to ensure that the intended package receives the message.
-     * <p>
-     * When an Android device dispatches an {@link NdefMessage}
-     * containing one or more Android application records,
-     * the applications contained in those records will be the
-     * preferred target for the {@link NfcAdapter#ACTION_NDEF_DISCOVERED}
-     * intent, in the order in which they appear in the message.
-     * This dispatch behavior was first added to Android in
-     * Ice Cream Sandwich.
-     * <p>
-     * If none of the applications have a are installed on the device,
-     * a Market link will be opened to the first application.
-     * <p>
-     * Note that Android application records do not overrule
-     * applications that have called
-     * {@link NfcAdapter#enableForegroundDispatch}.
-     *
-     * @param packageName Android package name
-     * @return Android application NDEF record
-     */
-    public static NdefRecord createApplicationRecord(String packageName) {
-        if (packageName == null) throw new NullPointerException("packageName is null");
-        if (packageName.length() == 0) throw new IllegalArgumentException("packageName is empty");
-
-        return new NdefRecord(TNF_EXTERNAL_TYPE, RTD_ANDROID_APP, null,
-                packageName.getBytes(StandardCharsets.UTF_8));
-    }
-
-    /**
-     * Create a new NDEF Record containing a URI.<p>
-     * Use this method to encode a URI (or URL) into an NDEF Record.<p>
-     * Uses the well known URI type representation: {@link #TNF_WELL_KNOWN}
-     * and {@link #RTD_URI}. This is the most efficient encoding
-     * of a URI into NDEF.<p>
-     * The uri parameter will be normalized with
-     * {@link Uri#normalizeScheme} to set the scheme to lower case to
-     * follow Android best practices for intent filtering.
-     * However the unchecked exception
-     * {@link IllegalArgumentException} may be thrown if the uri
-     * parameter has serious problems, for example if it is empty, so always
-     * catch this exception if you are passing user-generated data into this
-     * method.<p>
-     *
-     * Reference specification: NFCForum-TS-RTD_URI_1.0
-     *
-     * @param uri URI to encode.
-     * @return an NDEF Record containing the URI
-     * @throws IllegalArugmentException if the uri is empty or invalid
-     */
-    public static NdefRecord createUri(Uri uri) {
-        if (uri == null) throw new NullPointerException("uri is null");
-
-        uri = uri.normalizeScheme();
-        String uriString = uri.toString();
-        if (uriString.length() == 0) throw new IllegalArgumentException("uri is empty");
-
-        byte prefix = 0;
-        for (int i = 1; i < URI_PREFIX_MAP.length; i++) {
-            if (uriString.startsWith(URI_PREFIX_MAP[i])) {
-                prefix = (byte) i;
-                uriString = uriString.substring(URI_PREFIX_MAP[i].length());
-                break;
-            }
-        }
-        byte[] uriBytes = uriString.getBytes(StandardCharsets.UTF_8);
-        byte[] recordBytes = new byte[uriBytes.length + 1];
-        recordBytes[0] = prefix;
-        System.arraycopy(uriBytes, 0, recordBytes, 1, uriBytes.length);
-        return new NdefRecord(TNF_WELL_KNOWN, RTD_URI, null, recordBytes);
-    }
-
-    /**
-     * Create a new NDEF Record containing a URI.<p>
-     * Use this method to encode a URI (or URL) into an NDEF Record.<p>
-     * Uses the well known URI type representation: {@link #TNF_WELL_KNOWN}
-     * and {@link #RTD_URI}. This is the most efficient encoding
-     * of a URI into NDEF.<p>
-      * The uriString parameter will be normalized with
-     * {@link Uri#normalizeScheme} to set the scheme to lower case to
-     * follow Android best practices for intent filtering.
-     * However the unchecked exception
-     * {@link IllegalArgumentException} may be thrown if the uriString
-     * parameter has serious problems, for example if it is empty, so always
-     * catch this exception if you are passing user-generated data into this
-     * method.<p>
-     *
-     * Reference specification: NFCForum-TS-RTD_URI_1.0
-     *
-     * @param uriString string URI to encode.
-     * @return an NDEF Record containing the URI
-     * @throws IllegalArugmentException if the uriString is empty or invalid
-     */
-    public static NdefRecord createUri(String uriString) {
-        return createUri(Uri.parse(uriString));
-    }
-
-    /**
-     * Create a new NDEF Record containing MIME data.<p>
-     * Use this method to encode MIME-typed data into an NDEF Record,
-     * such as "text/plain", or "image/jpeg".<p>
-     * The mimeType parameter will be normalized with
-     * {@link Intent#normalizeMimeType} to follow Android best
-     * practices for intent filtering, for example to force lower-case.
-     * However the unchecked exception
-     * {@link IllegalArgumentException} may be thrown
-     * if the mimeType parameter has serious problems,
-     * for example if it is empty, so always catch this
-     * exception if you are passing user-generated data into this method.
-     * <p>
-     * For efficiency, This method might not make an internal copy of the
-     * mimeData byte array, so take care not
-     * to modify the mimeData byte array while still using the returned
-     * NdefRecord.
-     *
-     * @param mimeType a valid MIME type
-     * @param mimeData MIME data as bytes
-     * @return an NDEF Record containing the MIME-typed data
-     * @throws IllegalArugmentException if the mimeType is empty or invalid
-     *
-     */
-    public static NdefRecord createMime(String mimeType, byte[] mimeData) {
-        if (mimeType == null) throw new NullPointerException("mimeType is null");
-
-        // We only do basic MIME type validation: trying to follow the
-        // RFCs strictly only ends in tears, since there are lots of MIME
-        // types in common use that are not strictly valid as per RFC rules
-        mimeType = Intent.normalizeMimeType(mimeType);
-        if (mimeType.length() == 0) throw new IllegalArgumentException("mimeType is empty");
-        int slashIndex = mimeType.indexOf('/');
-        if (slashIndex == 0) throw new IllegalArgumentException("mimeType must have major type");
-        if (slashIndex == mimeType.length() - 1) {
-            throw new IllegalArgumentException("mimeType must have minor type");
-        }
-        // missing '/' is allowed
-
-        // MIME RFCs suggest ASCII encoding for content-type
-        byte[] typeBytes = mimeType.getBytes(StandardCharsets.US_ASCII);
-        return new NdefRecord(TNF_MIME_MEDIA, typeBytes, null, mimeData);
-    }
-
-    /**
-     * Create a new NDEF Record containing external (application-specific) data.<p>
-     * Use this method to encode application specific data into an NDEF Record.
-     * The data is typed by a domain name (usually your Android package name) and
-     * a domain-specific type. This data is packaged into a "NFC Forum External
-     * Type" NDEF Record.<p>
-     * NFC Forum requires that the domain and type used in an external record
-     * are treated as case insensitive, however Android intent filtering is
-     * always case sensitive. So this method will force the domain and type to
-     * lower-case before creating the NDEF Record.<p>
-     * The unchecked exception {@link IllegalArgumentException} will be thrown
-     * if the domain and type have serious problems, for example if either field
-     * is empty, so always catch this
-     * exception if you are passing user-generated data into this method.<p>
-     * There are no such restrictions on the payload data.<p>
-     * For efficiency, This method might not make an internal copy of the
-     * data byte array, so take care not
-     * to modify the data byte array while still using the returned
-     * NdefRecord.
-     *
-     * Reference specification: NFCForum-TS-RTD_1.0
-     * @param domain domain-name of issuing organization
-     * @param type domain-specific type of data
-     * @param data payload as bytes
-     * @throws IllegalArugmentException if either domain or type are empty or invalid
-     */
-    public static NdefRecord createExternal(String domain, String type, byte[] data) {
-        if (domain == null) throw new NullPointerException("domain is null");
-        if (type == null) throw new NullPointerException("type is null");
-
-        domain = domain.trim().toLowerCase(Locale.ROOT);
-        type = type.trim().toLowerCase(Locale.ROOT);
-
-        if (domain.length() == 0) throw new IllegalArgumentException("domain is empty");
-        if (type.length() == 0) throw new IllegalArgumentException("type is empty");
-
-        byte[] byteDomain = domain.getBytes(StandardCharsets.UTF_8);
-        byte[] byteType = type.getBytes(StandardCharsets.UTF_8);
-        byte[] b = new byte[byteDomain.length + 1 + byteType.length];
-        System.arraycopy(byteDomain, 0, b, 0, byteDomain.length);
-        b[byteDomain.length] = ':';
-        System.arraycopy(byteType, 0, b, byteDomain.length + 1, byteType.length);
-
-        return new NdefRecord(TNF_EXTERNAL_TYPE, b, null, data);
-    }
-
-    /**
-     * Create a new NDEF record containing UTF-8 text data.<p>
-     *
-     * The caller can either specify the language code for the provided text,
-     * or otherwise the language code corresponding to the current default
-     * locale will be used.
-     *
-     * Reference specification: NFCForum-TS-RTD_Text_1.0
-     * @param languageCode The languageCode for the record. If locale is empty or null,
-     *                     the language code of the current default locale will be used.
-     * @param text   The text to be encoded in the record. Will be represented in UTF-8 format.
-     * @throws IllegalArgumentException if text is null
-     */
-    public static NdefRecord createTextRecord(String languageCode, String text) {
-        if (text == null) throw new NullPointerException("text is null");
-
-        byte[] textBytes = text.getBytes(StandardCharsets.UTF_8);
-
-        byte[] languageCodeBytes = null;
-        if (languageCode != null && !languageCode.isEmpty()) {
-            languageCodeBytes = languageCode.getBytes(StandardCharsets.US_ASCII);
-        } else {
-            languageCodeBytes = Locale.getDefault().getLanguage().
-                    getBytes(StandardCharsets.US_ASCII);
-        }
-        // We only have 6 bits to indicate ISO/IANA language code.
-        if (languageCodeBytes.length >= 64) {
-            throw new IllegalArgumentException("language code is too long, must be <64 bytes.");
-        }
-        ByteBuffer buffer = ByteBuffer.allocate(1 + languageCodeBytes.length + textBytes.length);
-
-        byte status = (byte) (languageCodeBytes.length & 0xFF);
-        buffer.put(status);
-        buffer.put(languageCodeBytes);
-        buffer.put(textBytes);
-
-        return new NdefRecord(TNF_WELL_KNOWN, RTD_TEXT, null, buffer.array());
-    }
-
-    /**
-     * Construct an NDEF Record from its component fields.<p>
-     * Recommend to use helpers such as {#createUri} or
-     * {{@link #createExternal} where possible, since they perform
-     * stricter validation that the record is correctly formatted
-     * as per NDEF specifications. However if you know what you are
-     * doing then this constructor offers the most flexibility.<p>
-     * An {@link NdefRecord} represents a logical (complete)
-     * record, and cannot represent NDEF Record chunks.<p>
-     * Basic validation of the tnf, type, id and payload is performed
-     * as per the following rules:
-     * <ul>
-     * <li>The tnf paramter must be a 3-bit value.</li>
-     * <li>Records with a tnf of {@link #TNF_EMPTY} cannot have a type,
-     * id or payload.</li>
-     * <li>Records with a tnf of {@link #TNF_UNKNOWN} or {@literal 0x07}
-     * cannot have a type.</li>
-     * <li>Records with a tnf of {@link #TNF_UNCHANGED} are not allowed
-     * since this class only represents complete (unchunked) records.</li>
-     * </ul>
-     * This minimal validation is specified by
-     * NFCForum-TS-NDEF_1.0 section 3.2.6 (Type Name Format).<p>
-     * If any of the above validation
-     * steps fail then {@link IllegalArgumentException} is thrown.<p>
-     * Deep inspection of the type, id and payload fields is not
-     * performed, so it is possible to create NDEF Records
-     * that conform to section 3.2.6
-     * but fail other more strict NDEF specification requirements. For
-     * example, the payload may be invalid given the tnf and type.
-     * <p>
-     * To omit a type, id or payload field, set the parameter to an
-     * empty byte array or null.
-     *
-     * @param tnf  a 3-bit TNF constant
-     * @param type byte array, containing zero to 255 bytes, or null
-     * @param id   byte array, containing zero to 255 bytes, or null
-     * @param payload byte array, containing zero to (2 ** 32 - 1) bytes,
-     *                or null
-     * @throws IllegalArugmentException if a valid record cannot be created
-     */
-    public NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload) {
-        /* convert nulls */
-        if (type == null) type = EMPTY_BYTE_ARRAY;
-        if (id == null) id = EMPTY_BYTE_ARRAY;
-        if (payload == null) payload = EMPTY_BYTE_ARRAY;
-
-        String message = validateTnf(tnf, type, id, payload);
-        if (message != null) {
-            throw new IllegalArgumentException(message);
-        }
-
-        mTnf = tnf;
-        mType = type;
-        mId = id;
-        mPayload = payload;
-    }
-
-    /**
-     * Construct an NDEF Record from raw bytes.<p>
-     * This method is deprecated, use {@link NdefMessage#NdefMessage(byte[])}
-     * instead. This is because it does not make sense to parse a record:
-     * the NDEF binary format is only defined for a message, and the
-     * record flags MB and ME do not make sense outside of the context of
-     * an entire message.<p>
-     * This implementation will attempt to parse a single record by ignoring
-     * the MB and ME flags, and otherwise following the rules of
-     * {@link NdefMessage#NdefMessage(byte[])}.<p>
-     *
-     * @param data raw bytes to parse
-     * @throws FormatException if the data cannot be parsed into a valid record
-     * @deprecated use {@link NdefMessage#NdefMessage(byte[])} instead.
-     */
-    @Deprecated
-    public NdefRecord(byte[] data) throws FormatException {
-        ByteBuffer buffer = ByteBuffer.wrap(data);
-        NdefRecord[] rs = parse(buffer, true);
-
-        if (buffer.remaining() > 0) {
-            throw new FormatException("data too long");
-        }
-
-        mTnf = rs[0].mTnf;
-        mType = rs[0].mType;
-        mId = rs[0].mId;
-        mPayload = rs[0].mPayload;
-    }
-
-    /**
-     * Returns the 3-bit TNF.
-     * <p>
-     * TNF is the top-level type.
-     */
-    public short getTnf() {
-        return mTnf;
-    }
-
-    /**
-     * Returns the variable length Type field.
-     * <p>
-     * This should be used in conjunction with the TNF field to determine the
-     * payload format.
-     * <p>
-     * Returns an empty byte array if this record
-     * does not have a type field.
-     */
-    public byte[] getType() {
-        return mType.clone();
-    }
-
-    /**
-     * Returns the variable length ID.
-     * <p>
-     * Returns an empty byte array if this record
-     * does not have an id field.
-     */
-    public byte[] getId() {
-        return mId.clone();
-    }
-
-    /**
-     * Returns the variable length payload.
-     * <p>
-     * Returns an empty byte array if this record
-     * does not have a payload field.
-     */
-    public byte[] getPayload() {
-        return mPayload.clone();
-    }
-
-    /**
-     * Return this NDEF Record as a byte array.<p>
-     * This method is deprecated, use {@link NdefMessage#toByteArray}
-     * instead. This is because the NDEF binary format is not defined for
-     * a record outside of the context of a message: the MB and ME flags
-     * cannot be set without knowing the location inside a message.<p>
-     * This implementation will attempt to serialize a single record by
-     * always setting the MB and ME flags (in other words, assume this
-     * is a single-record NDEF Message).<p>
-     *
-     * @deprecated use {@link NdefMessage#toByteArray()} instead
-     */
-    @Deprecated
-    public byte[] toByteArray() {
-        ByteBuffer buffer = ByteBuffer.allocate(getByteLength());
-        writeToByteBuffer(buffer, true, true);
-        return buffer.array();
-    }
-
-    /**
-     * Map this record to a MIME type, or return null if it cannot be mapped.<p>
-     * Currently this method considers all {@link #TNF_MIME_MEDIA} records to
-     * be MIME records, as well as some {@link #TNF_WELL_KNOWN} records such as
-     * {@link #RTD_TEXT}. If this is a MIME record then the MIME type as string
-     * is returned, otherwise null is returned.<p>
-     * This method does not perform validation that the MIME type is
-     * actually valid. It always attempts to
-     * return a string containing the type if this is a MIME record.<p>
-     * The returned MIME type will by normalized to lower-case using
-     * {@link Intent#normalizeMimeType}.<p>
-     * The MIME payload can be obtained using {@link #getPayload}.
-     *
-     * @return MIME type as a string, or null if this is not a MIME record
-     */
-    public String toMimeType() {
-        switch (mTnf) {
-            case NdefRecord.TNF_WELL_KNOWN:
-                if (Arrays.equals(mType, NdefRecord.RTD_TEXT)) {
-                    return "text/plain";
-                }
-                break;
-            case NdefRecord.TNF_MIME_MEDIA:
-                String mimeType = new String(mType, StandardCharsets.US_ASCII);
-                return Intent.normalizeMimeType(mimeType);
-        }
-        return null;
-    }
-
-    /**
-     * Map this record to a URI, or return null if it cannot be mapped.<p>
-     * Currently this method considers the following to be URI records:
-     * <ul>
-     * <li>{@link #TNF_ABSOLUTE_URI} records.</li>
-     * <li>{@link #TNF_WELL_KNOWN} with a type of {@link #RTD_URI}.</li>
-     * <li>{@link #TNF_WELL_KNOWN} with a type of {@link #RTD_SMART_POSTER}
-     * and containing a URI record in the NDEF message nested in the payload.
-     * </li>
-     * <li>{@link #TNF_EXTERNAL_TYPE} records.</li>
-     * </ul>
-     * If this is not a URI record by the above rules, then null is returned.<p>
-     * This method does not perform validation that the URI is
-     * actually valid: it always attempts to create and return a URI if
-     * this record appears to be a URI record by the above rules.<p>
-     * The returned URI will be normalized to have a lower case scheme
-     * using {@link Uri#normalizeScheme}.<p>
-     *
-     * @return URI, or null if this is not a URI record
-     */
-    public Uri toUri() {
-        return toUri(false);
-    }
-
-    private Uri toUri(boolean inSmartPoster) {
-        switch (mTnf) {
-            case TNF_WELL_KNOWN:
-                if (Arrays.equals(mType, RTD_SMART_POSTER) && !inSmartPoster) {
-                    try {
-                        // check payload for a nested NDEF Message containing a URI
-                        NdefMessage nestedMessage = new NdefMessage(mPayload);
-                        for (NdefRecord nestedRecord : nestedMessage.getRecords()) {
-                            Uri uri = nestedRecord.toUri(true);
-                            if (uri != null) {
-                                return uri;
-                            }
-                        }
-                    } catch (FormatException e) {  }
-                } else if (Arrays.equals(mType, RTD_URI)) {
-                    Uri wktUri = parseWktUri();
-                    return (wktUri != null ? wktUri.normalizeScheme() : null);
-                }
-                break;
-
-            case TNF_ABSOLUTE_URI:
-                Uri uri = Uri.parse(new String(mType, StandardCharsets.UTF_8));
-                return uri.normalizeScheme();
-
-            case TNF_EXTERNAL_TYPE:
-                if (inSmartPoster) {
-                    break;
-                }
-                return Uri.parse("vnd.android.nfc://ext/" + new String(mType, StandardCharsets.US_ASCII));
-        }
-        return null;
-    }
-
-    /**
-     * Return complete URI of {@link #TNF_WELL_KNOWN}, {@link #RTD_URI} records.
-     * @return complete URI, or null if invalid
-     */
-    private Uri parseWktUri() {
-        if (mPayload.length < 2) {
-            return null;
-        }
-
-        // payload[0] contains the URI Identifier Code, as per
-        // NFC Forum "URI Record Type Definition" section 3.2.2.
-        int prefixIndex = (mPayload[0] & (byte)0xFF);
-        if (prefixIndex < 0 || prefixIndex >= URI_PREFIX_MAP.length) {
-            return null;
-        }
-        String prefix = URI_PREFIX_MAP[prefixIndex];
-        String suffix = new String(Arrays.copyOfRange(mPayload, 1, mPayload.length),
-                StandardCharsets.UTF_8);
-        return Uri.parse(prefix + suffix);
-    }
-
-    /**
-     * Main record parsing method.<p>
-     * Expects NdefMessage to begin immediately, allows trailing data.<p>
-     * Currently has strict validation of all fields as per NDEF 1.0
-     * specification section 2.5. We will attempt to keep this as strict as
-     * possible to encourage well-formatted NDEF.<p>
-     * Always returns 1 or more NdefRecord's, or throws FormatException.
-     *
-     * @param buffer ByteBuffer to read from
-     * @param ignoreMbMe ignore MB and ME flags, and read only 1 complete record
-     * @return one or more records
-     * @throws FormatException on any parsing error
-     */
-    static NdefRecord[] parse(ByteBuffer buffer, boolean ignoreMbMe) throws FormatException {
-        List<NdefRecord> records = new ArrayList<NdefRecord>();
-
-        try {
-            byte[] type = null;
-            byte[] id = null;
-            byte[] payload = null;
-            ArrayList<byte[]> chunks = new ArrayList<byte[]>();
-            boolean inChunk = false;
-            short chunkTnf = -1;
-            boolean me = false;
-
-            while (!me) {
-                byte flag = buffer.get();
-
-                boolean mb = (flag & NdefRecord.FLAG_MB) != 0;
-                me = (flag & NdefRecord.FLAG_ME) != 0;
-                boolean cf = (flag & NdefRecord.FLAG_CF) != 0;
-                boolean sr = (flag & NdefRecord.FLAG_SR) != 0;
-                boolean il = (flag & NdefRecord.FLAG_IL) != 0;
-                short tnf = (short)(flag & 0x07);
-
-                if (!mb && records.size() == 0 && !inChunk && !ignoreMbMe) {
-                    throw new FormatException("expected MB flag");
-                } else if (mb && (records.size() != 0 || inChunk) && !ignoreMbMe) {
-                    throw new FormatException("unexpected MB flag");
-                } else if (inChunk && il) {
-                    throw new FormatException("unexpected IL flag in non-leading chunk");
-                } else if (cf && me) {
-                    throw new FormatException("unexpected ME flag in non-trailing chunk");
-                } else if (inChunk && tnf != NdefRecord.TNF_UNCHANGED) {
-                    throw new FormatException("expected TNF_UNCHANGED in non-leading chunk");
-                } else if (!inChunk && tnf == NdefRecord.TNF_UNCHANGED) {
-                    throw new FormatException("" +
-                            "unexpected TNF_UNCHANGED in first chunk or unchunked record");
-                }
-
-                int typeLength = buffer.get() & 0xFF;
-                long payloadLength = sr ? (buffer.get() & 0xFF) : (buffer.getInt() & 0xFFFFFFFFL);
-                int idLength = il ? (buffer.get() & 0xFF) : 0;
-
-                if (inChunk && typeLength != 0) {
-                    throw new FormatException("expected zero-length type in non-leading chunk");
-                }
-
-                if (!inChunk) {
-                    type = (typeLength > 0 ? new byte[typeLength] : EMPTY_BYTE_ARRAY);
-                    id = (idLength > 0 ? new byte[idLength] : EMPTY_BYTE_ARRAY);
-                    buffer.get(type);
-                    buffer.get(id);
-                }
-
-                ensureSanePayloadSize(payloadLength);
-                payload = (payloadLength > 0 ? new byte[(int)payloadLength] : EMPTY_BYTE_ARRAY);
-                buffer.get(payload);
-
-                if (cf && !inChunk) {
-                    // first chunk
-                    if (typeLength == 0 && tnf != NdefRecord.TNF_UNKNOWN) {
-                        throw new FormatException("expected non-zero type length in first chunk");
-                    }
-                    chunks.clear();
-                    chunkTnf = tnf;
-                }
-                if (cf || inChunk) {
-                    // any chunk
-                    chunks.add(payload);
-                }
-                if (!cf && inChunk) {
-                    // last chunk, flatten the payload
-                    payloadLength = 0;
-                    for (byte[] p : chunks) {
-                        payloadLength += p.length;
-                    }
-                    ensureSanePayloadSize(payloadLength);
-                    payload = new byte[(int)payloadLength];
-                    int i = 0;
-                    for (byte[] p : chunks) {
-                        System.arraycopy(p, 0, payload, i, p.length);
-                        i += p.length;
-                    }
-                    tnf = chunkTnf;
-                }
-                if (cf) {
-                    // more chunks to come
-                    inChunk = true;
-                    continue;
-                } else {
-                    inChunk = false;
-                }
-
-                String error = validateTnf(tnf, type, id, payload);
-                if (error != null) {
-                    throw new FormatException(error);
-                }
-                records.add(new NdefRecord(tnf, type, id, payload));
-                if (ignoreMbMe) {  // for parsing a single NdefRecord
-                    break;
-                }
-            }
-        } catch (BufferUnderflowException e) {
-            throw new FormatException("expected more data", e);
-        }
-        return records.toArray(new NdefRecord[records.size()]);
-    }
-
-    private static void ensureSanePayloadSize(long size) throws FormatException {
-        if (size > MAX_PAYLOAD_SIZE) {
-            throw new FormatException(
-                    "payload above max limit: " + size + " > " + MAX_PAYLOAD_SIZE);
-        }
-    }
-
-    /**
-     * Perform simple validation that the tnf is valid.<p>
-     * Validates the requirements of NFCForum-TS-NDEF_1.0 section
-     * 3.2.6 (Type Name Format). This just validates that the tnf
-     * is valid, and that the relevant type, id and payload
-     * fields are present (or empty) for this tnf. It does not
-     * perform any deep inspection of the type, id and payload fields.<p>
-     * Also does not allow TNF_UNCHANGED since this class is only used
-     * to present logical (unchunked) records.
-     *
-     * @return null if valid, or a string error if invalid.
-     */
-    static String validateTnf(short tnf, byte[] type, byte[] id, byte[] payload) {
-        switch (tnf) {
-            case TNF_EMPTY:
-                if (type.length != 0 || id.length != 0 || payload.length != 0) {
-                    return "unexpected data in TNF_EMPTY record";
-                }
-                return null;
-            case TNF_WELL_KNOWN:
-            case TNF_MIME_MEDIA:
-            case TNF_ABSOLUTE_URI:
-            case TNF_EXTERNAL_TYPE:
-                return null;
-            case TNF_UNKNOWN:
-            case TNF_RESERVED:
-                if (type.length != 0) {
-                    return "unexpected type field in TNF_UNKNOWN or TNF_RESERVEd record";
-                }
-                return null;
-            case TNF_UNCHANGED:
-                return "unexpected TNF_UNCHANGED in first chunk or logical record";
-            default:
-                return String.format("unexpected tnf value: 0x%02x", tnf);
-        }
-    }
-
-    /**
-     * Serialize record for network transmission.<p>
-     * Uses specified MB and ME flags.<p>
-     * Does not chunk records.
-     */
-    void writeToByteBuffer(ByteBuffer buffer, boolean mb, boolean me) {
-        boolean sr = mPayload.length < 256;
-        boolean il = mTnf == TNF_EMPTY ? true : mId.length > 0;
-
-        byte flags = (byte)((mb ? FLAG_MB : 0) | (me ? FLAG_ME : 0) |
-                (sr ? FLAG_SR : 0) | (il ? FLAG_IL : 0) | mTnf);
-        buffer.put(flags);
-
-        buffer.put((byte)mType.length);
-        if (sr) {
-            buffer.put((byte)mPayload.length);
-        } else {
-            buffer.putInt(mPayload.length);
-        }
-        if (il) {
-            buffer.put((byte)mId.length);
-        }
-
-        buffer.put(mType);
-        buffer.put(mId);
-        buffer.put(mPayload);
-    }
-
-    /**
-     * Get byte length of serialized record.
-     */
-    int getByteLength() {
-        int length = 3 + mType.length + mId.length + mPayload.length;
-
-        boolean sr = mPayload.length < 256;
-        boolean il = mTnf == TNF_EMPTY ? true : mId.length > 0;
-
-        if (!sr) length += 3;
-        if (il) length += 1;
-
-        return length;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mTnf);
-        dest.writeInt(mType.length);
-        dest.writeByteArray(mType);
-        dest.writeInt(mId.length);
-        dest.writeByteArray(mId);
-        dest.writeInt(mPayload.length);
-        dest.writeByteArray(mPayload);
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<NdefRecord> CREATOR =
-            new Parcelable.Creator<NdefRecord>() {
-        @Override
-        public NdefRecord createFromParcel(Parcel in) {
-            short tnf = (short)in.readInt();
-            int typeLength = in.readInt();
-            byte[] type = new byte[typeLength];
-            in.readByteArray(type);
-            int idLength = in.readInt();
-            byte[] id = new byte[idLength];
-            in.readByteArray(id);
-            int payloadLength = in.readInt();
-            byte[] payload = new byte[payloadLength];
-            in.readByteArray(payload);
-
-            return new NdefRecord(tnf, type, id, payload);
-        }
-        @Override
-        public NdefRecord[] newArray(int size) {
-            return new NdefRecord[size];
-        }
-    };
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + Arrays.hashCode(mId);
-        result = prime * result + Arrays.hashCode(mPayload);
-        result = prime * result + mTnf;
-        result = prime * result + Arrays.hashCode(mType);
-        return result;
-    }
-
-    /**
-     * Returns true if the specified NDEF Record contains
-     * identical tnf, type, id and payload fields.
-     */
-    @Override
-    public boolean equals(@Nullable Object obj) {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        NdefRecord other = (NdefRecord) obj;
-        if (!Arrays.equals(mId, other.mId)) return false;
-        if (!Arrays.equals(mPayload, other.mPayload)) return false;
-        if (mTnf != other.mTnf) return false;
-        return Arrays.equals(mType, other.mType);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder b = new StringBuilder(String.format("NdefRecord tnf=%X", mTnf));
-        if (mType.length > 0) b.append(" type=").append(bytesToString(mType));
-        if (mId.length > 0) b.append(" id=").append(bytesToString(mId));
-        if (mPayload.length > 0) b.append(" payload=").append(bytesToString(mPayload));
-        return b.toString();
-    }
-
-    /**
-     * Dump debugging information as a NdefRecordProto
-     * @hide
-     *
-     * Note:
-     * See proto definition in frameworks/base/core/proto/android/nfc/ndef.proto
-     * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
-     * {@link ProtoOutputStream#end(long)} after.
-     * Never reuse a proto field number. When removing a field, mark it as reserved.
-     */
-    public void dumpDebug(ProtoOutputStream proto) {
-        proto.write(NdefRecordProto.TYPE, mType);
-        proto.write(NdefRecordProto.ID, mId);
-        proto.write(NdefRecordProto.PAYLOAD_BYTES, mPayload.length);
-    }
-
-    private static StringBuilder bytesToString(byte[] bs) {
-        StringBuilder s = new StringBuilder();
-        for (byte b : bs) {
-            s.append(String.format("%02X", b));
-        }
-        return s;
-    }
-}
diff --git a/nfc/java/android/nfc/NfcActivityManager.java b/nfc/java/android/nfc/NfcActivityManager.java
deleted file mode 100644
index 909eca7..0000000
--- a/nfc/java/android/nfc/NfcActivityManager.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * Copyright (C) 2011 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 android.nfc;
-
-import android.app.Activity;
-import android.app.Application;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.nfc.NfcAdapter.ReaderCallback;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Manages NFC API's that are coupled to the life-cycle of an Activity.
- *
- * <p>Uses {@link Application#registerActivityLifecycleCallbacks} to hook
- * into activity life-cycle events such as onPause() and onResume().
- *
- * @hide
- */
-public final class NfcActivityManager extends IAppCallback.Stub
-        implements Application.ActivityLifecycleCallbacks {
-    static final String TAG = NfcAdapter.TAG;
-    static final Boolean DBG = false;
-
-    @UnsupportedAppUsage
-    final NfcAdapter mAdapter;
-
-    // All objects in the lists are protected by this
-    final List<NfcApplicationState> mApps;  // Application(s) that have NFC state. Usually one
-    final List<NfcActivityState> mActivities;  // Activities that have NFC state
-
-    /**
-     * NFC State associated with an {@link Application}.
-     */
-    class NfcApplicationState {
-        int refCount = 0;
-        final Application app;
-        public NfcApplicationState(Application app) {
-            this.app = app;
-        }
-        public void register() {
-            refCount++;
-            if (refCount == 1) {
-                this.app.registerActivityLifecycleCallbacks(NfcActivityManager.this);
-            }
-        }
-        public void unregister() {
-            refCount--;
-            if (refCount == 0) {
-                this.app.unregisterActivityLifecycleCallbacks(NfcActivityManager.this);
-            } else if (refCount < 0) {
-                Log.e(TAG, "-ve refcount for " + app);
-            }
-        }
-    }
-
-    NfcApplicationState findAppState(Application app) {
-        for (NfcApplicationState appState : mApps) {
-            if (appState.app == app) {
-                return appState;
-            }
-        }
-        return null;
-    }
-
-    void registerApplication(Application app) {
-        NfcApplicationState appState = findAppState(app);
-        if (appState == null) {
-            appState = new NfcApplicationState(app);
-            mApps.add(appState);
-        }
-        appState.register();
-    }
-
-    void unregisterApplication(Application app) {
-        NfcApplicationState appState = findAppState(app);
-        if (appState == null) {
-            Log.e(TAG, "app was not registered " + app);
-            return;
-        }
-        appState.unregister();
-    }
-
-    /**
-     * NFC state associated with an {@link Activity}
-     */
-    class NfcActivityState {
-        boolean resumed = false;
-        Activity activity;
-        NfcAdapter.ReaderCallback readerCallback = null;
-        int readerModeFlags = 0;
-        Bundle readerModeExtras = null;
-        Binder token;
-
-        int mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
-        int mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;
-
-        public NfcActivityState(Activity activity) {
-            if (activity.isDestroyed()) {
-                throw new IllegalStateException("activity is already destroyed");
-            }
-            // Check if activity is resumed right now, as we will not
-            // immediately get a callback for that.
-            resumed = activity.isResumed();
-
-            this.activity = activity;
-            this.token = new Binder();
-            registerApplication(activity.getApplication());
-        }
-        public void destroy() {
-            unregisterApplication(activity.getApplication());
-            resumed = false;
-            activity = null;
-            readerCallback = null;
-            readerModeFlags = 0;
-            readerModeExtras = null;
-            token = null;
-
-            mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
-            mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;
-        }
-        @Override
-        public String toString() {
-            StringBuilder s = new StringBuilder("[");
-            s.append(readerCallback);
-            s.append("]");
-            return s.toString();
-        }
-    }
-
-    /** find activity state from mActivities */
-    synchronized NfcActivityState findActivityState(Activity activity) {
-        for (NfcActivityState state : mActivities) {
-            if (state.activity == activity) {
-                return state;
-            }
-        }
-        return null;
-    }
-
-    /** find or create activity state from mActivities */
-    synchronized NfcActivityState getActivityState(Activity activity) {
-        NfcActivityState state = findActivityState(activity);
-        if (state == null) {
-            state = new NfcActivityState(activity);
-            mActivities.add(state);
-        }
-        return state;
-    }
-
-    synchronized NfcActivityState findResumedActivityState() {
-        for (NfcActivityState state : mActivities) {
-            if (state.resumed) {
-                return state;
-            }
-        }
-        return null;
-    }
-
-    synchronized void destroyActivityState(Activity activity) {
-        NfcActivityState activityState = findActivityState(activity);
-        if (activityState != null) {
-            activityState.destroy();
-            mActivities.remove(activityState);
-        }
-    }
-
-    public NfcActivityManager(NfcAdapter adapter) {
-        mAdapter = adapter;
-        mActivities = new LinkedList<NfcActivityState>();
-        mApps = new ArrayList<NfcApplicationState>(1);  // Android VM usually has 1 app
-    }
-
-    public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
-            Bundle extras) {
-        boolean isResumed;
-        Binder token;
-        int pollTech, listenTech;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = getActivityState(activity);
-            state.readerCallback = callback;
-            state.readerModeFlags = flags;
-            state.readerModeExtras = extras;
-            pollTech = state.mPollTech;
-            listenTech = state.mListenTech;
-            token = state.token;
-            isResumed = state.resumed;
-        }
-        if (isResumed) {
-            if (listenTech != NfcAdapter.FLAG_USE_ALL_TECH
-                    || pollTech != NfcAdapter.FLAG_USE_ALL_TECH) {
-                throw new IllegalStateException(
-                    "Cannot be used when alternative DiscoveryTechnology is set");
-            } else {
-                setReaderMode(token, flags, extras);
-            }
-        }
-    }
-
-    public void disableReaderMode(Activity activity) {
-        boolean isResumed;
-        Binder token;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = getActivityState(activity);
-            state.readerCallback = null;
-            state.readerModeFlags = 0;
-            state.readerModeExtras = null;
-            token = state.token;
-            isResumed = state.resumed;
-        }
-        if (isResumed) {
-            setReaderMode(token, 0, null);
-        }
-
-    }
-
-    public void setReaderMode(Binder token, int flags, Bundle extras) {
-        if (DBG) Log.d(TAG, "Setting reader mode");
-        NfcAdapter.callService(() -> NfcAdapter.sService.setReaderMode(
-                token, this, flags, extras, mAdapter.getContext().getPackageName()));
-    }
-
-    /**
-     * Request or unrequest NFC service callbacks.
-     * Makes IPC call - do not hold lock.
-     */
-    void requestNfcServiceCallback() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.setAppCallback(this));
-    }
-
-    void verifyNfcPermission() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.verifyNfcPermission());
-    }
-
-    @Override
-    public void onTagDiscovered(Tag tag) throws RemoteException {
-        NfcAdapter.ReaderCallback callback;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = findResumedActivityState();
-            if (state == null) return;
-
-            callback = state.readerCallback;
-        }
-
-        // Make callback without lock
-        if (callback != null) {
-            callback.onTagDiscovered(tag);
-        }
-
-    }
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    public void onActivityCreated(Activity activity, Bundle savedInstanceState) { /* NO-OP */ }
-
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    public void onActivityStarted(Activity activity) { /* NO-OP */ }
-
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    public void onActivityResumed(Activity activity) {
-        int readerModeFlags = 0;
-        Bundle readerModeExtras = null;
-        Binder token;
-        int pollTech;
-        int listenTech;
-
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = findActivityState(activity);
-            if (DBG) Log.d(TAG, "onResume() for " + activity + " " + state);
-            if (state == null) return;
-            state.resumed = true;
-            token = state.token;
-            readerModeFlags = state.readerModeFlags;
-            readerModeExtras = state.readerModeExtras;
-
-            pollTech = state.mPollTech;
-            listenTech = state.mListenTech;
-        }
-        if (readerModeFlags != 0) {
-            setReaderMode(token, readerModeFlags, readerModeExtras);
-        } else if (listenTech != NfcAdapter.FLAG_USE_ALL_TECH
-                || pollTech != NfcAdapter.FLAG_USE_ALL_TECH) {
-            changeDiscoveryTech(token, pollTech, listenTech);
-        }
-        requestNfcServiceCallback();
-    }
-
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    public void onActivityPaused(Activity activity) {
-        boolean readerModeFlagsSet;
-        Binder token;
-        int pollTech;
-        int listenTech;
-
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = findActivityState(activity);
-            if (DBG) Log.d(TAG, "onPause() for " + activity + " " + state);
-            if (state == null) return;
-            state.resumed = false;
-            token = state.token;
-            readerModeFlagsSet = state.readerModeFlags != 0;
-
-            pollTech = state.mPollTech;
-            listenTech = state.mListenTech;
-        }
-        if (readerModeFlagsSet) {
-            // Restore default p2p modes
-            setReaderMode(token, 0, null);
-        } else if (listenTech != NfcAdapter.FLAG_USE_ALL_TECH
-                || pollTech != NfcAdapter.FLAG_USE_ALL_TECH) {
-            changeDiscoveryTech(token,
-                    NfcAdapter.FLAG_USE_ALL_TECH, NfcAdapter.FLAG_USE_ALL_TECH);
-        }
-    }
-
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    public void onActivityStopped(Activity activity) { /* NO-OP */ }
-
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    public void onActivitySaveInstanceState(Activity activity, Bundle outState) { /* NO-OP */ }
-
-    /** Callback from Activity life-cycle, on main thread */
-    @Override
-    public void onActivityDestroyed(Activity activity) {
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = findActivityState(activity);
-            if (DBG) Log.d(TAG, "onDestroy() for " + activity + " " + state);
-            if (state != null) {
-                // release all associated references
-                destroyActivityState(activity);
-            }
-        }
-    }
-
-    /** setDiscoveryTechnology() implementation */
-    public void setDiscoveryTech(Activity activity, int pollTech, int listenTech) {
-        boolean isResumed;
-        Binder token;
-        boolean readerModeFlagsSet;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = getActivityState(activity);
-            readerModeFlagsSet = state.readerModeFlags != 0;
-            state.mListenTech = listenTech;
-            state.mPollTech = pollTech;
-            token = state.token;
-            isResumed = state.resumed;
-        }
-        if (!readerModeFlagsSet && isResumed) {
-            changeDiscoveryTech(token, pollTech, listenTech);
-        } else if (readerModeFlagsSet) {
-            throw new IllegalStateException("Cannot be used when the Reader Mode is enabled");
-        }
-    }
-
-    /** resetDiscoveryTechnology() implementation */
-    public void resetDiscoveryTech(Activity activity) {
-        boolean isResumed;
-        Binder token;
-        boolean readerModeFlagsSet;
-        synchronized (NfcActivityManager.this) {
-            NfcActivityState state = getActivityState(activity);
-            state.mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;
-            state.mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
-            token = state.token;
-            isResumed = state.resumed;
-        }
-        if (isResumed) {
-            changeDiscoveryTech(token, NfcAdapter.FLAG_USE_ALL_TECH, NfcAdapter.FLAG_USE_ALL_TECH);
-        }
-
-    }
-
-    private void changeDiscoveryTech(Binder token, int pollTech, int listenTech) {
-        NfcAdapter.callService(
-                () -> NfcAdapter.sService.updateDiscoveryTechnology(
-                        token, pollTech, listenTech, mAdapter.getContext().getPackageName()));
-    }
-
-}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
deleted file mode 100644
index 63397c2..0000000
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ /dev/null
@@ -1,2949 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc;
-
-import android.Manifest;
-import android.annotation.CallbackExecutor;
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
-import android.annotation.UserIdInt;
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.net.Uri;
-import android.nfc.cardemulation.PollingFrame;
-import android.nfc.tech.MifareClassic;
-import android.nfc.tech.Ndef;
-import android.nfc.tech.NfcA;
-import android.nfc.tech.NfcF;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.Log;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-/**
- * Represents the local NFC adapter.
- * <p>
- * Use the helper {@link #getDefaultAdapter(Context)} to get the default NFC
- * adapter for this Android device.
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about using NFC, read the
- * <a href="{@docRoot}guide/topics/nfc/index.html">Near Field Communication</a> developer guide.</p>
- * <p>To perform basic file sharing between devices, read
- * <a href="{@docRoot}training/beam-files/index.html">Sharing Files with NFC</a>.
- * </div>
- */
-public final class NfcAdapter {
-    static final String TAG = "NFC";
-
-    private final NfcControllerAlwaysOnListener mControllerAlwaysOnListener;
-    private final NfcWlcStateListener mNfcWlcStateListener;
-    private final NfcVendorNciCallbackListener mNfcVendorNciCallbackListener;
-
-    /**
-     * Intent to start an activity when a tag with NDEF payload is discovered.
-     *
-     * <p>The system inspects the first {@link NdefRecord} in the first {@link NdefMessage} and
-     * looks for a URI, SmartPoster, or MIME record. If a URI or SmartPoster record is found the
-     * intent will contain the URI in its data field. If a MIME record is found the intent will
-     * contain the MIME type in its type field. This allows activities to register
-     * {@link IntentFilter}s targeting specific content on tags. Activities should register the
-     * most specific intent filters possible to avoid the activity chooser dialog, which can
-     * disrupt the interaction with the tag as the user interacts with the screen.
-     *
-     * <p>If the tag has an NDEF payload this intent is started before
-     * {@link #ACTION_TECH_DISCOVERED}. If any activities respond to this intent neither
-     * {@link #ACTION_TECH_DISCOVERED} or {@link #ACTION_TAG_DISCOVERED} will be started.
-     *
-     * <p>The MIME type or data URI of this intent are normalized before dispatch -
-     * so that MIME, URI scheme and URI host are always lower-case.
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
-
-    /**
-     * Intent to start an activity when a tag is discovered and activities are registered for the
-     * specific technologies on the tag.
-     *
-     * <p>To receive this intent an activity must include an intent filter
-     * for this action and specify the desired tech types in a
-     * manifest <code>meta-data</code> entry. Here is an example manfiest entry:
-     * <pre>
-     * &lt;activity android:name=".nfc.TechFilter" android:label="NFC/TechFilter"&gt;
-     *     &lt;!-- Add a technology filter --&gt;
-     *     &lt;intent-filter&gt;
-     *         &lt;action android:name="android.nfc.action.TECH_DISCOVERED" /&gt;
-     *     &lt;/intent-filter&gt;
-     *
-     *     &lt;meta-data android:name="android.nfc.action.TECH_DISCOVERED"
-     *         android:resource="@xml/filter_nfc"
-     *     /&gt;
-     * &lt;/activity&gt;</pre>
-     *
-     * <p>The meta-data XML file should contain one or more <code>tech-list</code> entries
-     * each consisting or one or more <code>tech</code> entries. The <code>tech</code> entries refer
-     * to the qualified class name implementing the technology, for example "android.nfc.tech.NfcA".
-     *
-     * <p>A tag matches if any of the
-     * <code>tech-list</code> sets is a subset of {@link Tag#getTechList() Tag.getTechList()}. Each
-     * of the <code>tech-list</code>s is considered independently and the
-     * activity is considered a match is any single <code>tech-list</code> matches the tag that was
-     * discovered. This provides AND and OR semantics for filtering desired techs. Here is an
-     * example that will match any tag using {@link NfcF} or any tag using {@link NfcA},
-     * {@link MifareClassic}, and {@link Ndef}:
-     *
-     * <pre>
-     * &lt;resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"&gt;
-     *     &lt;!-- capture anything using NfcF --&gt;
-     *     &lt;tech-list&gt;
-     *         &lt;tech&gt;android.nfc.tech.NfcF&lt;/tech&gt;
-     *     &lt;/tech-list&gt;
-     *
-     *     &lt;!-- OR --&gt;
-     *
-     *     &lt;!-- capture all MIFARE Classics with NDEF payloads --&gt;
-     *     &lt;tech-list&gt;
-     *         &lt;tech&gt;android.nfc.tech.NfcA&lt;/tech&gt;
-     *         &lt;tech&gt;android.nfc.tech.MifareClassic&lt;/tech&gt;
-     *         &lt;tech&gt;android.nfc.tech.Ndef&lt;/tech&gt;
-     *     &lt;/tech-list&gt;
-     * &lt;/resources&gt;</pre>
-     *
-     * <p>This intent is started after {@link #ACTION_NDEF_DISCOVERED} and before
-     * {@link #ACTION_TAG_DISCOVERED}. If any activities respond to {@link #ACTION_NDEF_DISCOVERED}
-     * this intent will not be started. If any activities respond to this intent
-     * {@link #ACTION_TAG_DISCOVERED} will not be started.
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED";
-
-    /**
-     * Intent to start an activity when a tag is discovered.
-     *
-     * <p>This intent will not be started when a tag is discovered if any activities respond to
-     * {@link #ACTION_NDEF_DISCOVERED} or {@link #ACTION_TECH_DISCOVERED} for the current tag.
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
-
-    /**
-     * Broadcast Action: Intent to notify an application that a transaction event has occurred
-     * on the Secure Element.
-     *
-     * <p>This intent will only be sent if the application has requested permission for
-     * {@link android.Manifest.permission#NFC_TRANSACTION_EVENT} and if the application has the
-     * necessary access to Secure Element which witnessed the particular event.
-     */
-    @RequiresPermission(android.Manifest.permission.NFC_TRANSACTION_EVENT)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_TRANSACTION_DETECTED =
-            "android.nfc.action.TRANSACTION_DETECTED";
-
-    /**
-     * Broadcast Action: Intent to notify if the preferred payment service changed.
-     *
-     * <p>This intent will only be sent to the application has requested permission for
-     * {@link android.Manifest.permission#NFC_PREFERRED_PAYMENT_INFO} and if the application
-     * has the necessary access to Secure Element which witnessed the particular event.
-     */
-    @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_PREFERRED_PAYMENT_CHANGED =
-            "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
-
-    /**
-     * Broadcast to only the activity that handles ACTION_TAG_DISCOVERED
-     * @hide
-     */
-    public static final String ACTION_TAG_LEFT_FIELD = "android.nfc.action.TAG_LOST";
-
-    /**
-     * Mandatory extra containing the {@link Tag} that was discovered for the
-     * {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and
-     * {@link #ACTION_TAG_DISCOVERED} intents.
-     */
-    public static final String EXTRA_TAG = "android.nfc.extra.TAG";
-
-    /**
-     * Extra containing an array of {@link NdefMessage} present on the discovered tag.<p>
-     * This extra is mandatory for {@link #ACTION_NDEF_DISCOVERED} intents,
-     * and optional for {@link #ACTION_TECH_DISCOVERED}, and
-     * {@link #ACTION_TAG_DISCOVERED} intents.<p>
-     * When this extra is present there will always be at least one
-     * {@link NdefMessage} element. Most NDEF tags have only one NDEF message,
-     * but we use an array for future compatibility.
-     */
-    public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
-
-    /**
-     * Optional extra containing a byte array containing the ID of the discovered tag for
-     * the {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and
-     * {@link #ACTION_TAG_DISCOVERED} intents.
-     */
-    public static final String EXTRA_ID = "android.nfc.extra.ID";
-
-    /**
-     * Broadcast Action: The state of the local NFC adapter has been
-     * changed.
-     * <p>For example, NFC has been turned on or off.
-     * <p>Always contains the extra field {@link #EXTRA_ADAPTER_STATE}
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_ADAPTER_STATE_CHANGED =
-            "android.nfc.action.ADAPTER_STATE_CHANGED";
-
-    /**
-     * Used as an int extra field in {@link #ACTION_ADAPTER_STATE_CHANGED}
-     * intents to request the current power state. Possible values are:
-     * {@link #STATE_OFF},
-     * {@link #STATE_TURNING_ON},
-     * {@link #STATE_ON},
-     * {@link #STATE_TURNING_OFF},
-     */
-    public static final String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE";
-
-    /**
-     * Mandatory byte[] extra field in {@link #ACTION_TRANSACTION_DETECTED}
-     */
-    public static final String EXTRA_AID = "android.nfc.extra.AID";
-
-    /**
-     * Optional byte[] extra field in {@link #ACTION_TRANSACTION_DETECTED}
-     */
-    public static final String EXTRA_DATA = "android.nfc.extra.DATA";
-
-    /**
-     * Mandatory String extra field in {@link #ACTION_TRANSACTION_DETECTED}
-     * Indicates the Secure Element on which the transaction occurred.
-     * eSE1...eSEn for Embedded Secure Elements, SIM1...SIMn for UICC/EUICC, etc.
-     */
-    public static final String EXTRA_SECURE_ELEMENT_NAME = "android.nfc.extra.SECURE_ELEMENT_NAME";
-
-    /**
-     * Mandatory String extra field in {@link #ACTION_PREFERRED_PAYMENT_CHANGED}
-     * Indicates the condition when trigger this event. Possible values are:
-     * {@link #PREFERRED_PAYMENT_LOADED},
-     * {@link #PREFERRED_PAYMENT_CHANGED},
-     * {@link #PREFERRED_PAYMENT_UPDATED},
-     */
-    public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON =
-            "android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON";
-    /**
-     * Nfc is enabled and the preferred payment aids are registered.
-     */
-    public static final int PREFERRED_PAYMENT_LOADED = 1;
-    /**
-     * User selected another payment application as the preferred payment.
-     */
-    public static final int PREFERRED_PAYMENT_CHANGED = 2;
-    /**
-     * Current preferred payment has issued an update (registered/unregistered new aids or has been
-     * updated itself).
-     */
-    public static final int PREFERRED_PAYMENT_UPDATED = 3;
-
-    public static final int STATE_OFF = 1;
-    public static final int STATE_TURNING_ON = 2;
-    public static final int STATE_ON = 3;
-    public static final int STATE_TURNING_OFF = 4;
-
-    /**
-     * Possible states from {@link #getAdapterState}.
-     *
-     * @hide
-     */
-    @IntDef(prefix = { "STATE_" }, value = {
-            STATE_OFF,
-            STATE_TURNING_ON,
-            STATE_ON,
-            STATE_TURNING_OFF
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface AdapterState{}
-
-    /**
-     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this flag enables polling for Nfc-A technology.
-     */
-    public static final int FLAG_READER_NFC_A = 0x1;
-
-    /**
-     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this flag enables polling for Nfc-B technology.
-     */
-    public static final int FLAG_READER_NFC_B = 0x2;
-
-    /**
-     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this flag enables polling for Nfc-F technology.
-     */
-    public static final int FLAG_READER_NFC_F = 0x4;
-
-    /**
-     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this flag enables polling for Nfc-V (ISO15693) technology.
-     */
-    public static final int FLAG_READER_NFC_V = 0x8;
-
-    /**
-     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this flag enables polling for NfcBarcode technology.
-     */
-    public static final int FLAG_READER_NFC_BARCODE = 0x10;
-
-    /** @hide */
-    @IntDef(flag = true, value = {
-        FLAG_SET_DEFAULT_TECH,
-        FLAG_READER_KEEP,
-        FLAG_READER_DISABLE,
-        FLAG_READER_NFC_A,
-        FLAG_READER_NFC_B,
-        FLAG_READER_NFC_F,
-        FLAG_READER_NFC_V,
-        FLAG_READER_NFC_BARCODE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface PollTechnology {}
-
-    /**
-     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this flag allows the caller to prevent the
-     * platform from performing an NDEF check on the tags it
-     * finds.
-     */
-    public static final int FLAG_READER_SKIP_NDEF_CHECK = 0x80;
-
-    /**
-     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this flag allows the caller to prevent the
-     * platform from playing sounds when it discovers a tag.
-     */
-    public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 0x100;
-
-    /**
-     * Int Extra for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
-     * <p>
-     * Setting this integer extra allows the calling application to specify
-     * the delay that the platform will use for performing presence checks
-     * on any discovered tag.
-     */
-    public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
-
-    /**
-     * Flag for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
-     * <p>
-     * Setting this flag enables listening for Nfc-A technology.
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
-    public static final int FLAG_LISTEN_NFC_PASSIVE_A = 0x1;
-
-    /**
-     * Flag for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
-     * <p>
-     * Setting this flag enables listening for Nfc-B technology.
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
-    public static final int FLAG_LISTEN_NFC_PASSIVE_B = 1 << 1;
-
-    /**
-     * Flag for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
-     * <p>
-     * Setting this flag enables listening for Nfc-F technology.
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
-    public static final int FLAG_LISTEN_NFC_PASSIVE_F = 1 << 2;
-
-    /**
-     * Flags for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
-     * <p>
-     * Setting this flag disables listening.
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
-    public static final int FLAG_LISTEN_DISABLE = 0x0;
-
-    /**
-     * Flags for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
-     * <p>
-     * Setting this flag disables polling.
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
-    public static final int FLAG_READER_DISABLE = 0x0;
-
-    /**
-     * Flags for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
-     * <p>
-     * Setting this flag makes listening to keep the current technology configuration.
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
-    public static final int FLAG_LISTEN_KEEP = 0x80000000;
-
-    /**
-     * Flags for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
-     * <p>
-     * Setting this flag makes polling to keep the current technology configuration.
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
-    public static final int FLAG_READER_KEEP = 0x80000000;
-
-    /** @hide */
-    public static final int FLAG_USE_ALL_TECH = 0xff;
-
-    /** @hide */
-    @IntDef(flag = true, value = {
-        FLAG_SET_DEFAULT_TECH,
-        FLAG_LISTEN_KEEP,
-        FLAG_LISTEN_DISABLE,
-        FLAG_LISTEN_NFC_PASSIVE_A,
-        FLAG_LISTEN_NFC_PASSIVE_B,
-        FLAG_LISTEN_NFC_PASSIVE_F
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ListenTechnology {}
-
-    /**
-     * Flag used in {@link #setDiscoveryTechnology(Activity, int, int)}.
-     * <p>
-     * Setting this flag changes the default listen or poll tech.
-     * Only available to privileged apps.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH)
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    public static final int FLAG_SET_DEFAULT_TECH = 0x40000000;
-
-    /**
-     * @hide
-     * @removed
-     */
-    @SystemApi
-    @UnsupportedAppUsage
-    public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 0x1;
-
-    /** @hide */
-    public static final String ACTION_HANDOVER_TRANSFER_STARTED =
-            "android.nfc.action.HANDOVER_TRANSFER_STARTED";
-
-    /** @hide */
-    public static final String ACTION_HANDOVER_TRANSFER_DONE =
-            "android.nfc.action.HANDOVER_TRANSFER_DONE";
-
-    /** @hide */
-    public static final String EXTRA_HANDOVER_TRANSFER_STATUS =
-            "android.nfc.extra.HANDOVER_TRANSFER_STATUS";
-
-    /** @hide */
-    public static final int HANDOVER_TRANSFER_STATUS_SUCCESS = 0;
-    /** @hide */
-    public static final int HANDOVER_TRANSFER_STATUS_FAILURE = 1;
-
-    /** @hide */
-    public static final String EXTRA_HANDOVER_TRANSFER_URI =
-            "android.nfc.extra.HANDOVER_TRANSFER_URI";
-
-    /**
-     * Broadcast Action: Notify possible NFC transaction blocked because device is locked.
-     * <p>An external NFC field detected when device locked and SecureNfc enabled.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
-    public static final String ACTION_REQUIRE_UNLOCK_FOR_NFC =
-            "android.nfc.action.REQUIRE_UNLOCK_FOR_NFC";
-
-    /**
-     * Intent action to start a NFC resolver activity in a customized share session with list of
-     * {@link ResolveInfo}.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
-    @RequiresPermission(Manifest.permission.SHOW_CUSTOMIZED_RESOLVER)
-    public static final String ACTION_SHOW_NFC_RESOLVER = "android.nfc.action.SHOW_NFC_RESOLVER";
-
-    /**
-     * "Extras" key for an ArrayList of {@link ResolveInfo} records which are to be shown as the
-     * targets in the customized share session.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
-    public static final String EXTRA_RESOLVE_INFOS = "android.nfc.extra.RESOLVE_INFOS";
-
-    /**
-     * The requested app is correctly added to the Tag intent app preference.
-     *
-     * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
-     * @hide
-     */
-    @SystemApi
-    public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0;
-
-    /**
-     * The requested app is not installed on the device.
-     *
-     * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
-     * @hide
-     */
-    @SystemApi
-    public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1;
-
-    /**
-     * The NfcService is not available.
-     *
-     * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
-     * @hide
-     */
-    @SystemApi
-    public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2;
-
-    /**
-     * Possible response codes from {@link #setTagIntentAppPreferenceForUser}.
-     *
-     * @hide
-     */
-    @IntDef(prefix = { "TAG_INTENT_APP_PREF_RESULT" }, value = {
-            TAG_INTENT_APP_PREF_RESULT_SUCCESS,
-            TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND,
-            TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface TagIntentAppPreferenceResult {}
-
-    /**
-     * Mode Type for {@link NfcOemExtension#setControllerAlwaysOnMode(int)}.
-     * @hide
-     */
-    public static final int CONTROLLER_ALWAYS_ON_MODE_DEFAULT = 1;
-
-    /**
-     * Mode Type for {@link NfcOemExtension#setControllerAlwaysOnMode(int)}.
-     * @hide
-     */
-    public static final int CONTROLLER_ALWAYS_ON_DISABLE = 0;
-
-    // Guarded by sLock
-    static boolean sIsInitialized = false;
-    static boolean sHasNfcFeature;
-    static boolean sHasCeFeature;
-    static boolean sHasNfcWlcFeature;
-
-    static Object sLock = new Object();
-
-    // Final after first constructor, except for
-    // attemptDeadServiceRecovery() when NFC crashes - we accept a best effort
-    // recovery
-    @UnsupportedAppUsage
-    static INfcAdapter sService;
-    static NfcServiceManager.ServiceRegisterer sServiceRegisterer;
-    static INfcTag sTagService;
-    static INfcCardEmulation sCardEmulationService;
-    static INfcFCardEmulation sNfcFCardEmulationService;
-    static IT4tNdefNfcee sNdefNfceeService;
-
-    /**
-     * The NfcAdapter object for each application context.
-     * There is a 1-1 relationship between application context and
-     * NfcAdapter object.
-     */
-    static HashMap<Context, NfcAdapter> sNfcAdapters = new HashMap(); //guard by NfcAdapter.class
-
-    /**
-     * NfcAdapter used with a null context. This ctor was deprecated but we have
-     * to support it for backwards compatibility. New methods that require context
-     * might throw when called on the null-context NfcAdapter.
-     */
-    static NfcAdapter sNullContextNfcAdapter;  // protected by NfcAdapter.class
-
-    final NfcActivityManager mNfcActivityManager;
-    final Context mContext;
-    final HashMap<NfcUnlockHandler, INfcUnlockHandler> mNfcUnlockHandlers;
-    final Object mLock;
-    final NfcOemExtension mNfcOemExtension;
-
-    ITagRemovedCallback mTagRemovedListener; // protected by mLock
-
-    /**
-     * A callback to be invoked when the system finds a tag while the foreground activity is
-     * operating in reader mode.
-     * <p>Register your {@code ReaderCallback} implementation with {@link
-     * NfcAdapter#enableReaderMode} and disable it with {@link
-     * NfcAdapter#disableReaderMode}.
-     * @see NfcAdapter#enableReaderMode
-     */
-    public interface ReaderCallback {
-        public void onTagDiscovered(Tag tag);
-    }
-
-    /**
-     * A listener to be invoked when NFC controller always on state changes.
-     * <p>Register your {@code ControllerAlwaysOnListener} implementation with {@link
-     * NfcAdapter#registerControllerAlwaysOnListener} and disable it with {@link
-     * NfcAdapter#unregisterControllerAlwaysOnListener}.
-     * @see #registerControllerAlwaysOnListener
-     * @hide
-     */
-    @SystemApi
-    public interface ControllerAlwaysOnListener {
-        /**
-         * Called on NFC controller always on state changes
-         */
-        void onControllerAlwaysOnChanged(boolean isEnabled);
-    }
-
-    /**
-     * A callback to be invoked when the system successfully delivers your {@link NdefMessage}
-     * to another device.
-     * @deprecated this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    public interface OnNdefPushCompleteCallback {
-        /**
-         * Called on successful NDEF push.
-         *
-         * <p>This callback is usually made on a binder thread (not the UI thread).
-         *
-         * @param event {@link NfcEvent} with the {@link NfcEvent#nfcAdapter} field set
-         */
-        public void onNdefPushComplete(NfcEvent event);
-    }
-
-    /**
-     * A callback to be invoked when another NFC device capable of NDEF push (Android Beam)
-     * is within range.
-     * <p>Implement this interface and pass it to {@code
-     * NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()} in order to create an
-     * {@link NdefMessage} at the moment that another device is within range for NFC. Using this
-     * callback allows you to create a message with data that might vary based on the
-     * content currently visible to the user. Alternatively, you can call {@code
-     * #setNdefPushMessage setNdefPushMessage()} if the {@link NdefMessage} always contains the
-     * same data.
-     * @deprecated this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    public interface CreateNdefMessageCallback {
-        /**
-         * Called to provide a {@link NdefMessage} to push.
-         *
-         * <p>This callback is usually made on a binder thread (not the UI thread).
-         *
-         * <p>Called when this device is in range of another device
-         * that might support NDEF push. It allows the application to
-         * create the NDEF message only when it is required.
-         *
-         * <p>NDEF push cannot occur until this method returns, so do not
-         * block for too long.
-         *
-         * <p>The Android operating system will usually show a system UI
-         * on top of your activity during this time, so do not try to request
-         * input from the user to complete the callback, or provide custom NDEF
-         * push UI. The user probably will not see it.
-         *
-         * @param event {@link NfcEvent} with the {@link NfcEvent#nfcAdapter} field set
-         * @return NDEF message to push, or null to not provide a message
-         */
-        public NdefMessage createNdefMessage(NfcEvent event);
-    }
-
-
-     /**
-     * @deprecated this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    public interface CreateBeamUrisCallback {
-        public Uri[] createBeamUris(NfcEvent event);
-    }
-
-    /**
-     * A callback that is invoked when a tag is removed from the field.
-     * @see NfcAdapter#ignore
-     */
-    public interface OnTagRemovedListener {
-        void onTagRemoved();
-    }
-
-    /**
-     * A callback to be invoked when an application has registered as a
-     * handler to unlock the device given an NFC tag at the lockscreen.
-     * @hide
-     */
-    @SystemApi
-    public interface NfcUnlockHandler {
-        /**
-         * Called at the lock screen to attempt to unlock the device with the given tag.
-         * @param tag the detected tag, to be used to unlock the device
-         * @return true if the device was successfully unlocked
-         */
-        public boolean onUnlockAttempted(Tag tag);
-    }
-
-    /**
-     * Return list of Secure Elements which support off host card emulation.
-     *
-     * @return List<String> containing secure elements on the device which supports
-     *                      off host card emulation. eSE for Embedded secure element,
-     *                      SIM for UICC/EUICC and so on.
-     * @hide
-     */
-    public @NonNull List<String> getSupportedOffHostSecureElements() {
-        if (mContext == null) {
-            throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
-                    + " getSupportedOffHostSecureElements APIs");
-        }
-        List<String> offHostSE = new ArrayList<String>();
-        PackageManager pm = mContext.getPackageManager();
-        if (pm == null) {
-            Log.e(TAG, "Cannot get package manager, assuming no off-host CE feature");
-            return offHostSE;
-        }
-        if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC)) {
-            offHostSE.add("SIM");
-        }
-        if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE)) {
-            offHostSE.add("eSE");
-        }
-        return offHostSE;
-    }
-
-    private static void retrieveServiceRegisterer() {
-        if (sServiceRegisterer == null) {
-            NfcServiceManager manager = NfcFrameworkInitializer.getNfcServiceManager();
-            if (manager == null) {
-                Log.e(TAG, "NfcServiceManager is null");
-                throw new UnsupportedOperationException();
-            }
-            sServiceRegisterer = manager.getNfcManagerServiceRegisterer();
-        }
-    }
-
-    /**
-     * Returns the NfcAdapter for application context,
-     * or throws if NFC is not available.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static synchronized NfcAdapter getNfcAdapter(Context context) {
-        if (context == null) {
-            if (sNullContextNfcAdapter == null) {
-                sNullContextNfcAdapter = new NfcAdapter(null);
-            }
-            return sNullContextNfcAdapter;
-        }
-        if (!sIsInitialized) {
-            PackageManager pm;
-            pm = context.getPackageManager();
-            sHasNfcFeature = pm.hasSystemFeature(PackageManager.FEATURE_NFC);
-            sHasCeFeature =
-                    pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
-                    || pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)
-                    || pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC)
-                    || pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE);
-            sHasNfcWlcFeature = pm.hasSystemFeature(PackageManager.FEATURE_NFC_CHARGING);
-            /* is this device meant to have NFC */
-            if (!sHasNfcFeature && !sHasCeFeature && !sHasNfcWlcFeature) {
-                Log.v(TAG, "this device does not have NFC support");
-                throw new UnsupportedOperationException();
-            }
-            retrieveServiceRegisterer();
-            sService = getServiceInterface();
-            if (sService == null) {
-                Log.e(TAG, "could not retrieve NFC service");
-                throw new UnsupportedOperationException();
-            }
-            if (sHasNfcFeature) {
-                try {
-                    sTagService = sService.getNfcTagInterface();
-                } catch (RemoteException e) {
-                    sTagService = null;
-                    Log.e(TAG, "could not retrieve NFC Tag service");
-                    throw new UnsupportedOperationException();
-                }
-            }
-            if (sHasCeFeature) {
-                try {
-                    sNfcFCardEmulationService = sService.getNfcFCardEmulationInterface();
-                } catch (RemoteException e) {
-                    sNfcFCardEmulationService = null;
-                    Log.e(TAG, "could not retrieve NFC-F card emulation service");
-                    throw new UnsupportedOperationException();
-                }
-                try {
-                    sCardEmulationService = sService.getNfcCardEmulationInterface();
-                } catch (RemoteException e) {
-                    sCardEmulationService = null;
-                    Log.e(TAG, "could not retrieve card emulation service");
-                    throw new UnsupportedOperationException();
-                }
-            }
-            try {
-                sNdefNfceeService = sService.getT4tNdefNfceeInterface();
-            } catch (RemoteException e) {
-                sNdefNfceeService = null;
-                Log.e(TAG, "could not retrieve NDEF NFCEE service");
-                throw new UnsupportedOperationException();
-            }
-            sIsInitialized = true;
-        }
-        NfcAdapter adapter = sNfcAdapters.get(context);
-        if (adapter == null) {
-            adapter = new NfcAdapter(context);
-            sNfcAdapters.put(context, adapter);
-        }
-        return adapter;
-    }
-
-    /** get handle to NFC service interface */
-    private static INfcAdapter getServiceInterface() {
-        /* get a handle to NFC service */
-        IBinder b = sServiceRegisterer.get();
-        if (b == null) {
-            return null;
-        }
-        return INfcAdapter.Stub.asInterface(b);
-    }
-
-    /**
-     * Helper to get the default NFC Adapter.
-     * <p>
-     * Most Android devices will only have one NFC Adapter (NFC Controller).
-     * <p>
-     * This helper is the equivalent of:
-     * <pre>
-     * NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
-     * NfcAdapter adapter = manager.getDefaultAdapter();</pre>
-     * @param context the calling application's context
-     *
-     * @return the default NFC adapter, or null if no NFC adapter exists
-     */
-    public static NfcAdapter getDefaultAdapter(Context context) {
-        if (context == null) {
-            throw new IllegalArgumentException("context cannot be null");
-        }
-        context = context.getApplicationContext();
-        if (context == null) {
-            throw new IllegalArgumentException(
-                    "context not associated with any application (using a mock context?)");
-        }
-        retrieveServiceRegisterer();
-        if (sServiceRegisterer.tryGet() == null) {
-            if (sIsInitialized) {
-                synchronized (NfcAdapter.class) {
-                    /* Stale sService pointer */
-                    if (sIsInitialized) sIsInitialized = false;
-                }
-            }
-            return null;
-        }
-        /* Try to initialize the service */
-        NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
-        if (manager == null) {
-            // NFC not available
-            return null;
-        }
-        return manager.getDefaultAdapter();
-    }
-
-    /**
-     * Legacy NfcAdapter getter, always use {@link #getDefaultAdapter(Context)} instead.<p>
-     * This method was deprecated at API level 10 (Gingerbread MR1) because a context is required
-     * for many NFC API methods. Those methods will fail when called on an NfcAdapter
-     * object created from this method.<p>
-     * @deprecated use {@link #getDefaultAdapter(Context)}
-     * @hide
-     */
-    @Deprecated
-    @UnsupportedAppUsage
-    public static NfcAdapter getDefaultAdapter() {
-        // introduced in API version 9 (GB 2.3)
-        // deprecated in API version 10 (GB 2.3.3)
-        // removed from public API in version 16 (ICS MR2)
-        // should maintain as a hidden API for binary compatibility for a little longer
-        Log.w(TAG, "WARNING: NfcAdapter.getDefaultAdapter() is deprecated, use " +
-                "NfcAdapter.getDefaultAdapter(Context) instead", new Exception());
-
-        return NfcAdapter.getNfcAdapter(null);
-    }
-
-    NfcAdapter(Context context) {
-        mContext = context;
-        mNfcActivityManager = new NfcActivityManager(this);
-        mNfcUnlockHandlers = new HashMap<NfcUnlockHandler, INfcUnlockHandler>();
-        mTagRemovedListener = null;
-        mLock = new Object();
-        mControllerAlwaysOnListener = new NfcControllerAlwaysOnListener(getService());
-        mNfcWlcStateListener = new NfcWlcStateListener(getService());
-        mNfcVendorNciCallbackListener = new NfcVendorNciCallbackListener(getService());
-        mNfcOemExtension = new NfcOemExtension(mContext, this);
-    }
-
-    /**
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public Context getContext() {
-        return mContext;
-    }
-
-    /**
-     * Returns the binder interface to the service.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static INfcAdapter getService() {
-        isEnabledStatic();  // NOP call to recover sService if it is stale
-        return sService;
-    }
-
-    /**
-     * Returns the binder interface to the tag service.
-     * @hide
-     */
-    public static INfcTag getTagService() {
-        isEnabledStatic();  // NOP call to recover sTagService if it is stale
-        return sTagService;
-    }
-
-    /**
-     * Returns the binder interface to the card emulation service.
-     * @hide
-     */
-    public static INfcCardEmulation getCardEmulationService() {
-        isEnabledStatic();
-        return sCardEmulationService;
-    }
-
-    /**
-     * Returns the binder interface to the NFC-F card emulation service.
-     * @hide
-     */
-    public static INfcFCardEmulation getNfcFCardEmulationService() {
-        isEnabledStatic();
-        return sNfcFCardEmulationService;
-    }
-
-    /**
-     * Returns the binder interface to the NFC-DTA test interface.
-     * @hide
-     */
-    public INfcDta getNfcDtaInterface() {
-        if (mContext == null) {
-            throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
-                    + " NFC extras APIs");
-        }
-        return callServiceReturn(() ->  sService.getNfcDtaInterface(mContext.getPackageName()),
-                null);
-
-    }
-
-    /**
-     * NFC service dead - attempt best effort recovery
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static void attemptDeadServiceRecovery(RemoteException e) {
-        Log.e(TAG, "NFC service dead - attempting to recover", e);
-        INfcAdapter service = getServiceInterface();
-        if (service == null) {
-            Log.e(TAG, "could not retrieve NFC service during service recovery");
-            // nothing more can be done now, sService is still stale, we'll hit
-            // this recovery path again later
-            e.rethrowAsRuntimeException();
-        }
-        // assigning to sService is not thread-safe, but this is best-effort code
-        // and on a well-behaved system should never happen
-        sService = service;
-        if (sHasNfcFeature) {
-            try {
-                sTagService = service.getNfcTagInterface();
-            } catch (RemoteException ee) {
-                sTagService = null;
-                Log.e(TAG, "could not retrieve NFC tag service during service recovery");
-                // nothing more can be done now, sService is still stale, we'll hit
-                // this recovery path again later
-                ee.rethrowAsRuntimeException();
-            }
-        }
-
-        if (sHasCeFeature) {
-            try {
-                sCardEmulationService = service.getNfcCardEmulationInterface();
-            } catch (RemoteException ee) {
-                sCardEmulationService = null;
-                Log.e(TAG,
-                        "could not retrieve NFC card emulation service during service recovery");
-            }
-
-            try {
-                sNfcFCardEmulationService = service.getNfcFCardEmulationInterface();
-            } catch (RemoteException ee) {
-                sNfcFCardEmulationService = null;
-                Log.e(TAG,
-                        "could not retrieve NFC-F card emulation service during service recovery");
-            }
-        }
-    }
-
-    private static boolean isCardEmulationEnabled() {
-        if (sHasCeFeature) {
-            return (sCardEmulationService != null || sNfcFCardEmulationService != null);
-        }
-        return false;
-    }
-
-    private static boolean isTagReadingEnabled() {
-        if (sHasNfcFeature) {
-            return sTagService != null;
-        }
-        return false;
-    }
-
-    private static boolean isEnabledStatic() {
-        boolean serviceState = callServiceReturn(() -> sService.getState() == STATE_ON, false);
-        return serviceState
-                && (isTagReadingEnabled() || isCardEmulationEnabled() || sHasNfcWlcFeature);
-    }
-
-    /**
-     * Return true if this NFC Adapter has any features enabled.
-     *
-     * <p>If this method returns false, the NFC hardware is guaranteed not to
-     * generate or respond to any NFC communication over its NFC radio.
-     * <p>Applications can use this to check if NFC is enabled. Applications
-     * can request Settings UI allowing the user to toggle NFC using:
-     * <p><pre>startActivity(new Intent(Settings.ACTION_NFC_SETTINGS))</pre>
-     *
-     * @see android.provider.Settings#ACTION_NFC_SETTINGS
-     * @return true if this NFC Adapter has any features enabled
-     */
-    public boolean isEnabled() {
-        return isEnabledStatic();
-    }
-
-    /**
-     * Return the state of this NFC Adapter.
-     *
-     * <p>Returns one of {@link #STATE_ON}, {@link #STATE_TURNING_ON},
-     * {@link #STATE_OFF}, {@link #STATE_TURNING_OFF}.
-     *
-     * <p>{@link #isEnabled()} is equivalent to
-     * <code>{@link #getAdapterState()} == {@link #STATE_ON}</code>
-     *
-     * @return the current state of this NFC adapter
-     *
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
-    public @AdapterState int getAdapterState() {
-        return callServiceReturn(() ->  sService.getState(), NfcAdapter.STATE_OFF);
-
-    }
-
-    /**
-     * Enable NFC hardware.
-     *
-     * <p>This call is asynchronous. Listen for
-     * {@link #ACTION_ADAPTER_STATE_CHANGED} broadcasts to find out when the
-     * operation is complete.
-     *
-     * <p>This API is only allowed to be called by system apps
-     * or apps which are Device Owner or Profile Owner.
-     *
-     * <p>If this returns true, then either NFC is already on, or
-     * a {@link #ACTION_ADAPTER_STATE_CHANGED} broadcast will be sent
-     * to indicate a state transition. If this returns false, then
-     * there is some problem that prevents an attempt to turn
-     * NFC on (for example we are in airplane mode and NFC is not
-     * toggleable in airplane mode on this platform).
-     *
-     */
-    @FlaggedApi(Flags.FLAG_NFC_STATE_CHANGE)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean enable() {
-        return callServiceReturn(() ->  sService.enable(mContext.getPackageName()), false);
-
-    }
-
-    /**
-     * Disable NFC hardware.
-     *
-     * <p>No NFC features will work after this call, and the hardware
-     * will not perform or respond to any NFC communication.
-     *
-     * <p>This call is asynchronous. Listen for
-     * {@link #ACTION_ADAPTER_STATE_CHANGED} broadcasts to find out when the
-     * operation is complete.
-     *
-     * <p>This API is only allowed to be called by system apps
-     * or apps which are Device Owner or Profile Owner.
-     *
-     * <p>If this returns true, then either NFC is already off, or
-     * a {@link #ACTION_ADAPTER_STATE_CHANGED} broadcast will be sent
-     * to indicate a state transition. If this returns false, then
-     * there is some problem that prevents an attempt to turn
-     * NFC off.
-     *
-     */
-    @FlaggedApi(Flags.FLAG_NFC_STATE_CHANGE)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean disable() {
-        return callServiceReturn(() ->  sService.disable(true, mContext.getPackageName()),
-                false);
-
-    }
-
-    /**
-     * Disable NFC hardware.
-     * @hide
-    */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean disable(boolean persist) {
-        return callServiceReturn(() ->  sService.disable(persist, mContext.getPackageName()),
-                false);
-
-    }
-
-    /**
-     * Pauses NFC tag reader mode polling for a {@code timeoutInMs} millisecond.
-     * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely
-     * use {@link #resumePolling() to resume the polling.
-     * @hide
-     */
-    public void pausePolling(int timeoutInMs) {
-        callService(() -> sService.pausePolling(timeoutInMs));
-    }
-
-
-    /**
-     * Returns whether the device supports observe mode or not. When observe mode is enabled, the
-     * NFC hardware will listen to NFC readers, but not respond to them. While enabled, observed
-     * polling frames will be sent to the APDU service (see {@link #setObserveModeEnabled(boolean)}.
-     * When observe mode is disabled (or if it's not supported), the NFC hardware will automatically
-     * respond to the reader and proceed with the transaction.
-     * @return true if the mode is supported, false otherwise.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
-    public boolean isObserveModeSupported() {
-        return callServiceReturn(() ->  sService.isObserveModeSupported(), false);
-    }
-
-    /**
-     * Returns whether Observe Mode is currently enabled or not.
-     *
-     * @return true if observe mode is enabled, false otherwise.
-     */
-
-    @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
-    public boolean isObserveModeEnabled() {
-        return callServiceReturn(() ->  sService.isObserveModeEnabled(), false);
-    }
-
-    /**
-     * Controls whether the NFC adapter will allow transactions to proceed or be in observe mode
-     * and simply observe and notify the APDU service of polling loop frames. See
-     * {@link #isObserveModeSupported()} for a description of observe mode. Only the package of the
-     * currently preferred service (the service set as preferred by the current foreground
-     * application via {@link android.nfc.cardemulation.CardEmulation#setPreferredService(Activity,
-     * android.content.ComponentName)} or the current Default Wallet Role Holder
-     * {@link android.app.role.RoleManager#ROLE_WALLET}), otherwise a call to this method will fail
-     * and return false.
-     *
-     * @param enabled false disables observe mode to allow the transaction to proceed while true
-     *                enables observe mode and does not allow transactions to proceed.
-     *
-     * @return boolean indicating success or failure.
-     */
-
-    @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
-    public boolean setObserveModeEnabled(boolean enabled) {
-        if (mContext == null) {
-            throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
-                    + " observe mode APIs");
-        }
-        return callServiceReturn(() ->  sService.setObserveMode(enabled, mContext.getPackageName()),
-                false);
-    }
-
-    /**
-     * Resumes default NFC tag reader mode polling for the current device state if polling is
-     * paused. Calling this while already in polling is a no-op.
-     * @hide
-     */
-    public void resumePolling() {
-        callService(() -> sService.resumePolling());
-    }
-
-    /**
-     * Set one or more {@link Uri}s to send using Android Beam (TM). Every
-     * Uri you provide must have either scheme 'file' or scheme 'content'.
-     *
-     * <p>For the data provided through this method, Android Beam tries to
-     * switch to alternate transports such as Bluetooth to achieve a fast
-     * transfer speed. Hence this method is very suitable
-     * for transferring large files such as pictures or songs.
-     *
-     * <p>The receiving side will store the content of each Uri in
-     * a file and present a notification to the user to open the file
-     * with a {@link android.content.Intent} with action
-     * {@link android.content.Intent#ACTION_VIEW}.
-     * If multiple URIs are sent, the {@link android.content.Intent} will refer
-     * to the first of the stored files.
-     *
-     * <p>This method may be called at any time before {@link Activity#onDestroy},
-     * but the URI(s) are only made available for Android Beam when the
-     * specified activity(s) are in resumed (foreground) state. The recommended
-     * approach is to call this method during your Activity's
-     * {@link Activity#onCreate} - see sample
-     * code below. This method does not immediately perform any I/O or blocking work,
-     * so is safe to call on your main thread.
-     *
-     * <p>{@link #setBeamPushUris} and {@link #setBeamPushUrisCallback}
-     * have priority over both {@link #setNdefPushMessage} and
-     * {@link #setNdefPushMessageCallback}.
-     *
-     * <p>If {@link #setBeamPushUris} is called with a null Uri array,
-     * and/or {@link #setBeamPushUrisCallback} is called with a null callback,
-     * then the Uri push will be completely disabled for the specified activity(s).
-     *
-     * <p>Code example:
-     * <pre>
-     * protected void onCreate(Bundle savedInstanceState) {
-     *     super.onCreate(savedInstanceState);
-     *     NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
-     *     if (nfcAdapter == null) return;  // NFC not available on this device
-     *     nfcAdapter.setBeamPushUris(new Uri[] {uri1, uri2}, this);
-     * }</pre>
-     * And that is it. Only one call per activity is necessary. The Android
-     * OS will automatically release its references to the Uri(s) and the
-     * Activity object when it is destroyed if you follow this pattern.
-     *
-     * <p>If your Activity wants to dynamically supply Uri(s),
-     * then set a callback using {@link #setBeamPushUrisCallback} instead
-     * of using this method.
-     *
-     * <p class="note">Do not pass in an Activity that has already been through
-     * {@link Activity#onDestroy}. This is guaranteed if you call this API
-     * during {@link Activity#onCreate}.
-     *
-     * <p class="note">If this device does not support alternate transports
-     * such as Bluetooth or WiFI, calling this method does nothing.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param uris an array of Uri(s) to push over Android Beam
-     * @param activity activity for which the Uri(s) will be pushed
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public void setBeamPushUris(Uri[] uris, Activity activity) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Set a callback that will dynamically generate one or more {@link Uri}s
-     * to send using Android Beam (TM). Every Uri the callback provides
-     * must have either scheme 'file' or scheme 'content'.
-     *
-     * <p>For the data provided through this callback, Android Beam tries to
-     * switch to alternate transports such as Bluetooth to achieve a fast
-     * transfer speed. Hence this method is very suitable
-     * for transferring large files such as pictures or songs.
-     *
-     * <p>The receiving side will store the content of each Uri in
-     * a file and present a notification to the user to open the file
-     * with a {@link android.content.Intent} with action
-     * {@link android.content.Intent#ACTION_VIEW}.
-     * If multiple URIs are sent, the {@link android.content.Intent} will refer
-     * to the first of the stored files.
-     *
-     * <p>This method may be called at any time before {@link Activity#onDestroy},
-     * but the URI(s) are only made available for Android Beam when the
-     * specified activity(s) are in resumed (foreground) state. The recommended
-     * approach is to call this method during your Activity's
-     * {@link Activity#onCreate} - see sample
-     * code below. This method does not immediately perform any I/O or blocking work,
-     * so is safe to call on your main thread.
-     *
-     * <p>{@link #setBeamPushUris} and {@link #setBeamPushUrisCallback}
-     * have priority over both {@link #setNdefPushMessage} and
-     * {@link #setNdefPushMessageCallback}.
-     *
-     * <p>If {@link #setBeamPushUris} is called with a null Uri array,
-     * and/or {@link #setBeamPushUrisCallback} is called with a null callback,
-     * then the Uri push will be completely disabled for the specified activity(s).
-     *
-     * <p>Code example:
-     * <pre>
-     * protected void onCreate(Bundle savedInstanceState) {
-     *     super.onCreate(savedInstanceState);
-     *     NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
-     *     if (nfcAdapter == null) return;  // NFC not available on this device
-     *     nfcAdapter.setBeamPushUrisCallback(callback, this);
-     * }</pre>
-     * And that is it. Only one call per activity is necessary. The Android
-     * OS will automatically release its references to the Uri(s) and the
-     * Activity object when it is destroyed if you follow this pattern.
-     *
-     * <p class="note">Do not pass in an Activity that has already been through
-     * {@link Activity#onDestroy}. This is guaranteed if you call this API
-     * during {@link Activity#onCreate}.
-     *
-     * <p class="note">If this device does not support alternate transports
-     * such as Bluetooth or WiFI, calling this method does nothing.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param callback callback, or null to disable
-     * @param activity activity for which the Uri(s) will be pushed
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Set a static {@link NdefMessage} to send using Android Beam (TM).
-     *
-     * <p>This method may be called at any time before {@link Activity#onDestroy},
-     * but the NDEF message is only made available for NDEF push when the
-     * specified activity(s) are in resumed (foreground) state. The recommended
-     * approach is to call this method during your Activity's
-     * {@link Activity#onCreate} - see sample
-     * code below. This method does not immediately perform any I/O or blocking work,
-     * so is safe to call on your main thread.
-     *
-     * <p>Only one NDEF message can be pushed by the currently resumed activity.
-     * If both {@link #setNdefPushMessage} and
-     * {@link #setNdefPushMessageCallback} are set, then
-     * the callback will take priority.
-     *
-     * <p>If neither {@link #setNdefPushMessage} or
-     * {@link #setNdefPushMessageCallback} have been called for your activity, then
-     * the Android OS may choose to send a default NDEF message on your behalf,
-     * such as a URI for your application.
-     *
-     * <p>If {@link #setNdefPushMessage} is called with a null NDEF message,
-     * and/or {@link #setNdefPushMessageCallback} is called with a null callback,
-     * then NDEF push will be completely disabled for the specified activity(s).
-     * This also disables any default NDEF message the Android OS would have
-     * otherwise sent on your behalf for those activity(s).
-     *
-     * <p>If you want to prevent the Android OS from sending default NDEF
-     * messages completely (for all activities), you can include a
-     * {@code <meta-data>} element inside the {@code <application>}
-     * element of your AndroidManifest.xml file, like this:
-     * <pre>
-     * &lt;application ...>
-     *     &lt;meta-data android:name="android.nfc.disable_beam_default"
-     *         android:value="true" />
-     * &lt;/application></pre>
-     *
-     * <p>The API allows for multiple activities to be specified at a time,
-     * but it is strongly recommended to just register one at a time,
-     * and to do so during the activity's {@link Activity#onCreate}. For example:
-     * <pre>
-     * protected void onCreate(Bundle savedInstanceState) {
-     *     super.onCreate(savedInstanceState);
-     *     NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
-     *     if (nfcAdapter == null) return;  // NFC not available on this device
-     *     nfcAdapter.setNdefPushMessage(ndefMessage, this);
-     * }</pre>
-     * And that is it. Only one call per activity is necessary. The Android
-     * OS will automatically release its references to the NDEF message and the
-     * Activity object when it is destroyed if you follow this pattern.
-     *
-     * <p>If your Activity wants to dynamically generate an NDEF message,
-     * then set a callback using {@link #setNdefPushMessageCallback} instead
-     * of a static message.
-     *
-     * <p class="note">Do not pass in an Activity that has already been through
-     * {@link Activity#onDestroy}. This is guaranteed if you call this API
-     * during {@link Activity#onCreate}.
-     *
-     * <p class="note">For sending large content such as pictures and songs,
-     * consider using {@link #setBeamPushUris}, which switches to alternate transports
-     * such as Bluetooth to achieve a fast transfer rate.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param message NDEF message to push over NFC, or null to disable
-     * @param activity activity for which the NDEF message will be pushed
-     * @param activities optional additional activities, however we strongly recommend
-     *        to only register one at a time, and to do so in that activity's
-     *        {@link Activity#onCreate}
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public void setNdefPushMessage(NdefMessage message, Activity activity,
-            Activity ... activities) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * @hide
-     * @removed
-     */
-    @SystemApi
-    @UnsupportedAppUsage
-    public void setNdefPushMessage(NdefMessage message, Activity activity, int flags) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Set a callback that dynamically generates NDEF messages to send using Android Beam (TM).
-     *
-     * <p>This method may be called at any time before {@link Activity#onDestroy},
-     * but the NDEF message callback can only occur when the
-     * specified activity(s) are in resumed (foreground) state. The recommended
-     * approach is to call this method during your Activity's
-     * {@link Activity#onCreate} - see sample
-     * code below. This method does not immediately perform any I/O or blocking work,
-     * so is safe to call on your main thread.
-     *
-     * <p>Only one NDEF message can be pushed by the currently resumed activity.
-     * If both {@link #setNdefPushMessage} and
-     * {@link #setNdefPushMessageCallback} are set, then
-     * the callback will take priority.
-     *
-     * <p>If neither {@link #setNdefPushMessage} or
-     * {@link #setNdefPushMessageCallback} have been called for your activity, then
-     * the Android OS may choose to send a default NDEF message on your behalf,
-     * such as a URI for your application.
-     *
-     * <p>If {@link #setNdefPushMessage} is called with a null NDEF message,
-     * and/or {@link #setNdefPushMessageCallback} is called with a null callback,
-     * then NDEF push will be completely disabled for the specified activity(s).
-     * This also disables any default NDEF message the Android OS would have
-     * otherwise sent on your behalf for those activity(s).
-     *
-     * <p>If you want to prevent the Android OS from sending default NDEF
-     * messages completely (for all activities), you can include a
-     * {@code <meta-data>} element inside the {@code <application>}
-     * element of your AndroidManifest.xml file, like this:
-     * <pre>
-     * &lt;application ...>
-     *     &lt;meta-data android:name="android.nfc.disable_beam_default"
-     *         android:value="true" />
-     * &lt;/application></pre>
-     *
-     * <p>The API allows for multiple activities to be specified at a time,
-     * but it is strongly recommended to just register one at a time,
-     * and to do so during the activity's {@link Activity#onCreate}. For example:
-     * <pre>
-     * protected void onCreate(Bundle savedInstanceState) {
-     *     super.onCreate(savedInstanceState);
-     *     NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
-     *     if (nfcAdapter == null) return;  // NFC not available on this device
-     *     nfcAdapter.setNdefPushMessageCallback(callback, this);
-     * }</pre>
-     * And that is it. Only one call per activity is necessary. The Android
-     * OS will automatically release its references to the callback and the
-     * Activity object when it is destroyed if you follow this pattern.
-     *
-     * <p class="note">Do not pass in an Activity that has already been through
-     * {@link Activity#onDestroy}. This is guaranteed if you call this API
-     * during {@link Activity#onCreate}.
-     * <p class="note">For sending large content such as pictures and songs,
-     * consider using {@link #setBeamPushUris}, which switches to alternate transports
-     * such as Bluetooth to achieve a fast transfer rate.
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param callback callback, or null to disable
-     * @param activity activity for which the NDEF message will be pushed
-     * @param activities optional additional activities, however we strongly recommend
-     *        to only register one at a time, and to do so in that activity's
-     *        {@link Activity#onCreate}
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
-            Activity ... activities) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Set a callback on successful Android Beam (TM).
-     *
-     * <p>This method may be called at any time before {@link Activity#onDestroy},
-     * but the callback can only occur when the
-     * specified activity(s) are in resumed (foreground) state. The recommended
-     * approach is to call this method during your Activity's
-     * {@link Activity#onCreate} - see sample
-     * code below. This method does not immediately perform any I/O or blocking work,
-     * so is safe to call on your main thread.
-     *
-     * <p>The API allows for multiple activities to be specified at a time,
-     * but it is strongly recommended to just register one at a time,
-     * and to do so during the activity's {@link Activity#onCreate}. For example:
-     * <pre>
-     * protected void onCreate(Bundle savedInstanceState) {
-     *     super.onCreate(savedInstanceState);
-     *     NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
-     *     if (nfcAdapter == null) return;  // NFC not available on this device
-     *     nfcAdapter.setOnNdefPushCompleteCallback(callback, this);
-     * }</pre>
-     * And that is it. Only one call per activity is necessary. The Android
-     * OS will automatically release its references to the callback and the
-     * Activity object when it is destroyed if you follow this pattern.
-     *
-     * <p class="note">Do not pass in an Activity that has already been through
-     * {@link Activity#onDestroy}. This is guaranteed if you call this API
-     * during {@link Activity#onCreate}.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param callback callback, or null to disable
-     * @param activity activity for which the NDEF message will be pushed
-     * @param activities optional additional activities, however we strongly recommend
-     *        to only register one at a time, and to do so in that activity's
-     *        {@link Activity#onCreate}
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public void setOnNdefPushCompleteCallback(OnNdefPushCompleteCallback callback,
-            Activity activity, Activity ... activities) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Enable foreground dispatch to the given Activity.
-     *
-     * <p>This will give priority to the foreground activity when
-     * dispatching a discovered {@link Tag} to an application.
-     *
-     * <p>If any IntentFilters are provided to this method they are used to match dispatch Intents
-     * for both the {@link NfcAdapter#ACTION_NDEF_DISCOVERED} and
-     * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. Since {@link NfcAdapter#ACTION_TECH_DISCOVERED}
-     * relies on meta data outside of the IntentFilter matching for that dispatch Intent is handled
-     * by passing in the tech lists separately. Each first level entry in the tech list represents
-     * an array of technologies that must all be present to match. If any of the first level sets
-     * match then the dispatch is routed through the given PendingIntent. In other words, the second
-     * level is ANDed together and the first level entries are ORed together.
-     *
-     * <p>If you pass {@code null} for both the {@code filters} and {@code techLists} parameters
-     * that acts a wild card and will cause the foreground activity to receive all tags via the
-     * {@link NfcAdapter#ACTION_TAG_DISCOVERED} intent.
-     *
-     * <p>This method must be called from the main thread, and only when the activity is in the
-     * foreground (resumed). Also, activities must call {@link #disableForegroundDispatch} before
-     * the completion of their {@link Activity#onPause} callback to disable foreground dispatch
-     * after it has been enabled.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param activity the Activity to dispatch to
-     * @param intent the PendingIntent to start for the dispatch
-     * @param filters the IntentFilters to override dispatching for, or null to always dispatch
-     * @param techLists the tech lists used to perform matching for dispatching of the
-     *      {@link NfcAdapter#ACTION_TECH_DISCOVERED} intent
-     * @throws IllegalStateException if the Activity is not currently in the foreground
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     */
-    public void enableForegroundDispatch(Activity activity, PendingIntent intent,
-            IntentFilter[] filters, String[][] techLists) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        if (activity == null || intent == null) {
-            throw new NullPointerException();
-        }
-        final TechListParcel parcel = (techLists != null && techLists.length > 0)
-            ? new TechListParcel(techLists)
-            : null;
-        callService(() -> sService.setForegroundDispatch(intent, filters, parcel));
-    }
-
-    /**
-     * Disable foreground dispatch to the given activity.
-     *
-     * <p>After calling {@link #enableForegroundDispatch}, an activity
-     * must call this method before its {@link Activity#onPause} callback
-     * completes.
-     *
-     * <p>This method must be called from the main thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param activity the Activity to disable dispatch to
-     * @throws IllegalStateException if the Activity has already been paused
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     */
-    public void disableForegroundDispatch(Activity activity) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        callService(() -> sService.setForegroundDispatch(null, null, null));
-    }
-
-    /**
-     * Limit the NFC controller to reader mode while this Activity is in the foreground.
-     *
-     * <p>In this mode the NFC controller will only act as an NFC tag reader/writer,
-     * thus disabling any peer-to-peer (Android Beam) and card-emulation modes of
-     * the NFC adapter on this device.
-     *
-     * <p>Use {@link #FLAG_READER_SKIP_NDEF_CHECK} to prevent the platform from
-     * performing any NDEF checks in reader mode. Note that this will prevent the
-     * {@link Ndef} tag technology from being enumerated on the tag, and that
-     * NDEF-based tag dispatch will not be functional.
-     *
-     * <p>For interacting with tags that are emulated on another Android device
-     * using Android's host-based card-emulation, the recommended flags are
-     * {@link #FLAG_READER_NFC_A} and {@link #FLAG_READER_SKIP_NDEF_CHECK}.
-     *
-     * @param activity the Activity that requests the adapter to be in reader mode
-     * @param callback the callback to be called when a tag is discovered
-     * @param flags Flags indicating poll technologies and other optional parameters
-     * @param extras Additional extras for configuring reader mode.
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     */
-    public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
-            Bundle extras) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        mNfcActivityManager.enableReaderMode(activity, callback, flags, extras);
-    }
-
-    /**
-     * Restore the NFC adapter to normal mode of operation: supporting
-     * peer-to-peer (Android Beam), card emulation, and polling for
-     * all supported tag technologies.
-     *
-     * @param activity the Activity that currently has reader mode enabled
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     */
-    public void disableReaderMode(Activity activity) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        mNfcActivityManager.disableReaderMode(activity);
-    }
-
-    // Flags arguments to NFC adapter to enable/disable NFC
-    private static final int DISABLE_POLLING_FLAGS = 0x1000;
-    private static final int ENABLE_POLLING_FLAGS = 0x0000;
-
-    /**
-     * Privileged API to enable or disable reader polling.
-     * Unlike {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}, this API does not
-     * need a foreground activity to control reader mode parameters
-     * Note: Use with caution! The app is responsible for ensuring that the polling state is
-     * returned to normal.
-     *
-     * @see #enableReaderMode(Activity, ReaderCallback, int, Bundle)  for more detailed
-     * documentation.
-     *
-     * @param enablePolling whether to enable or disable polling.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
-    @SuppressLint("VisiblySynchronized")
-    public void setReaderModePollingEnabled(boolean enable) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        Binder token = new Binder();
-        int flags = enable ? ENABLE_POLLING_FLAGS : DISABLE_POLLING_FLAGS;
-        callService(() -> sService.setReaderMode(
-                token, null, flags, null, mContext.getPackageName()));
-    }
-
-    /**
-     * Set the NFC controller to enable specific poll/listen technologies,
-     * as specified in parameters, while this Activity is in the foreground.
-     *
-     * Use {@link #FLAG_READER_KEEP} to keep current polling technology.
-     * Use {@link #FLAG_LISTEN_KEEP} to keep current listenig technology.
-     * (if the _KEEP flag is specified the other technology flags shouldn't be set
-     * and are quietly ignored otherwise).
-     * Use {@link #FLAG_READER_DISABLE} to disable polling.
-     * Use {@link #FLAG_LISTEN_DISABLE} to disable listening.
-     * Also refer to {@link #resetDiscoveryTechnology(Activity)} to restore these changes.
-     * </p>
-     * The pollTechnology, listenTechnology parameters can be one or several of below list.
-     * <pre>
-     *                    Poll                    Listen
-     *  Passive A         0x01   (NFC_A)           0x01  (NFC_PASSIVE_A)
-     *  Passive B         0x02   (NFC_B)           0x02  (NFC_PASSIVE_B)
-     *  Passive F         0x04   (NFC_F)           0x04  (NFC_PASSIVE_F)
-     *  ISO 15693         0x08   (NFC_V)             -
-     *  Kovio             0x10   (NFC_BARCODE)       -
-     * </pre>
-     * <p>Example usage in an Activity that requires to disable poll,
-     * keep current listen technologies:
-     * <pre>
-     * protected void onResume() {
-     *     mNfcAdapter = NfcAdapter.getDefaultAdapter(getApplicationContext());
-     *     mNfcAdapter.setDiscoveryTechnology(this,
-     *         NfcAdapter.FLAG_READER_DISABLE, NfcAdapter.FLAG_LISTEN_KEEP);
-     * }</pre></p>
-     * @param activity The Activity that requests NFC controller to enable specific technologies.
-     * @param pollTechnology Flags indicating poll technologies.
-     * @param listenTechnology Flags indicating listen technologies.
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF are unavailable.
-     *
-     * NOTE: This API overrides all technology flags regardless of the current device state,
-     *       it is incompatible with enableReaderMode() API and the others that either update
-     *       or assume any techlology flag set by the OS.
-     *       Please use with care.
-     */
-
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
-    public void setDiscoveryTechnology(@NonNull Activity activity,
-            @PollTechnology int pollTechnology, @ListenTechnology int listenTechnology) {
-
-        if (listenTechnology == FLAG_LISTEN_DISABLE) {
-            synchronized (sLock) {
-                if (!sHasNfcFeature) {
-                    throw new UnsupportedOperationException();
-                }
-            }
-        } else if (pollTechnology == FLAG_READER_DISABLE) {
-            synchronized (sLock) {
-                if (!sHasCeFeature) {
-                    throw new UnsupportedOperationException();
-                }
-            }
-        } else {
-            synchronized (sLock) {
-                if (!sHasNfcFeature || !sHasCeFeature) {
-                    throw new UnsupportedOperationException();
-                }
-            }
-        }
-    /*
-     * Privileged FLAG to set technology mask for all data processed by NFC controller
-     * Note: Use with caution! The app is responsible for ensuring that the discovery
-     * technology mask is returned to default.
-     * Note: FLAG_USE_ALL_TECH used with _KEEP flags will reset the technolody to android default
-     */
-        if (Flags.nfcSetDefaultDiscTech()
-                && ((pollTechnology & FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH
-                || (listenTechnology & FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {
-            Binder token = new Binder();
-            callService( () ->
-                    sService.updateDiscoveryTechnology(
-                            token, pollTechnology, listenTechnology, mContext.getPackageName()));
-        } else {
-            mNfcActivityManager.setDiscoveryTech(activity, pollTechnology, listenTechnology);
-        }
-    }
-
-    /**
-     * Restore the poll/listen technologies of NFC controller to its default state,
-     * which were changed by {@link #setDiscoveryTechnology(Activity , int , int)}
-     *
-     * @param activity The Activity that requested to change technologies.
-     */
-
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
-    public void resetDiscoveryTechnology(@NonNull Activity activity) {
-        mNfcActivityManager.resetDiscoveryTech(activity);
-    }
-
-    /**
-     * Manually invoke Android Beam to share data.
-     *
-     * <p>The Android Beam animation is normally only shown when two NFC-capable
-     * devices come into range.
-     * By calling this method, an Activity can invoke the Beam animation directly
-     * even if no other NFC device is in range yet. The Beam animation will then
-     * prompt the user to tap another NFC-capable device to complete the data
-     * transfer.
-     *
-     * <p>The main advantage of using this method is that it avoids the need for the
-     * user to tap the screen to complete the transfer, as this method already
-     * establishes the direction of the transfer and the consent of the user to
-     * share data. Callers are responsible for making sure that the user has
-     * consented to sharing data on NFC tap.
-     *
-     * <p>Note that to use this method, the passed in Activity must have already
-     * set data to share over Beam by using method calls such as
-     * {@link #setNdefPushMessageCallback} or
-     * {@link #setBeamPushUrisCallback}.
-     *
-     * @param activity the current foreground Activity that has registered data to share
-     * @return whether the Beam animation was successfully invoked
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public boolean invokeBeam(Activity activity) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Enable NDEF message push over NFC while this Activity is in the foreground.
-     *
-     * <p>You must explicitly call this method every time the activity is
-     * resumed, and you must call {@link #disableForegroundNdefPush} before
-     * your activity completes {@link Activity#onPause}.
-     *
-     * <p>Strongly recommend to use the new {@link #setNdefPushMessage}
-     * instead: it automatically hooks into your activity life-cycle,
-     * so you do not need to call enable/disable in your onResume/onPause.
-     *
-     * <p>For NDEF push to function properly the other NFC device must
-     * support either NFC Forum's SNEP (Simple Ndef Exchange Protocol), or
-     * Android's "com.android.npp" (Ndef Push Protocol). This was optional
-     * on Gingerbread level Android NFC devices, but SNEP is mandatory on
-     * Ice-Cream-Sandwich and beyond.
-     *
-     * <p>This method must be called from the main thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param activity foreground activity
-     * @param message a NDEF Message to push over NFC
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @Deprecated
-    @UnsupportedAppUsage
-    public void enableForegroundNdefPush(Activity activity, NdefMessage message) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Disable NDEF message push over P2P.
-     *
-     * <p>After calling {@link #enableForegroundNdefPush}, an activity
-     * must call this method before its {@link Activity#onPause} callback
-     * completes.
-     *
-     * <p>Strongly recommend to use the new {@link #setNdefPushMessage}
-     * instead: it automatically hooks into your activity life-cycle,
-     * so you do not need to call enable/disable in your onResume/onPause.
-     *
-     * <p>This method must be called from the main thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param activity the Foreground activity
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @Deprecated
-    @UnsupportedAppUsage
-    public void disableForegroundNdefPush(Activity activity) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-    }
-
-    /**
-     * Sets Secure NFC feature.
-     * <p>This API is for the Settings application.
-     * @return True if successful
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean enableSecureNfc(boolean enable) {
-        if (!sHasNfcFeature && !sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.setNfcSecure(enable), false);
-
-    }
-
-    /**
-     * Checks if the device supports Secure NFC functionality.
-     *
-     * @return True if device supports Secure NFC, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     * are unavailable
-     */
-    public boolean isSecureNfcSupported() {
-        if (!sHasNfcFeature && !sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.deviceSupportsNfcSecure(), false);
-
-    }
-
-    /**
-     * Returns information regarding Nfc antennas on the device
-     * such as their relative positioning on the device.
-     *
-     * @return Information on the nfc antenna(s) on the device.
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     * are unavailable
-     */
-    @Nullable
-    public NfcAntennaInfo getNfcAntennaInfo() {
-        if (!sHasNfcFeature && !sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.getNfcAntennaInfo(), null);
-
-    }
-
-    /**
-     * Checks Secure NFC feature is enabled.
-     *
-     * @return True if Secure NFC is enabled, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     * are unavailable
-     * @throws UnsupportedOperationException if device doesn't support
-     *         Secure NFC functionality. {@link #isSecureNfcSupported}
-     */
-    public boolean isSecureNfcEnabled() {
-        if (!sHasNfcFeature && !sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.isNfcSecureEnabled(), false);
-
-    }
-
-    /**
-     * Sets NFC Reader option feature.
-     * <p>This API is for the Settings application.
-     * @return True if successful
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_READER_OPTION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean enableReaderOption(boolean enable) {
-        if (!sHasNfcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->
-                sService.enableReaderOption(enable, mContext.getPackageName()), false);
-
-    }
-
-    /**
-     * Checks if the device supports NFC Reader option functionality.
-     *
-     * @return True if device supports NFC Reader option, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_READER_OPTION)
-    public boolean isReaderOptionSupported() {
-        if (!sHasNfcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.isReaderOptionSupported(), false);
-
-    }
-
-    /**
-     * Checks NFC Reader option feature is enabled.
-     *
-     * @return True if NFC Reader option  is enabled, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @throws UnsupportedOperationException if device doesn't support
-     *         NFC Reader option functionality. {@link #isReaderOptionSupported}
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_READER_OPTION)
-    public boolean isReaderOptionEnabled() {
-        if (!sHasNfcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.isReaderOptionEnabled(), false);
-
-    }
-
-    /**
-     * Enable NDEF Push feature.
-     * <p>This API is for the Settings application.
-     * @hide
-     * @removed
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @UnsupportedAppUsage
-    public boolean enableNdefPush() {
-        return false;
-    }
-
-    /**
-     * Disable NDEF Push feature.
-     * <p>This API is for the Settings application.
-     * @hide
-     * @removed
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @UnsupportedAppUsage
-    public boolean disableNdefPush() {
-        return false;
-    }
-
-    /**
-     * Return true if the NDEF Push (Android Beam) feature is enabled.
-     * <p>This function will return true only if both NFC is enabled, and the
-     * NDEF Push feature is enabled.
-     * <p>Note that if NFC is enabled but NDEF Push is disabled then this
-     * device can still <i>receive</i> NDEF messages, it just cannot send them.
-     * <p>Applications cannot directly toggle the NDEF Push feature, but they
-     * can request Settings UI allowing the user to toggle NDEF Push using
-     * <code>startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS))</code>
-     * <p>Example usage in an Activity that requires NDEF Push:
-     * <p><pre>
-     * protected void onResume() {
-     *     super.onResume();
-     *     if (!nfcAdapter.isEnabled()) {
-     *         startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
-     *     } else if (!nfcAdapter.isNdefPushEnabled()) {
-     *         startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS));
-     *     }
-     * }</pre>
-     *
-     * @see android.provider.Settings#ACTION_NFCSHARING_SETTINGS
-     * @return true if NDEF Push feature is enabled
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @removed this feature is removed. File sharing can work using other technology like
-     * Bluetooth.
-     */
-    @java.lang.Deprecated
-    @UnsupportedAppUsage
-    public boolean isNdefPushEnabled() {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Signals that you are no longer interested in communicating with an NFC tag
-     * for as long as it remains in range.
-     *
-     * All future attempted communication to this tag will fail with {@link IOException}.
-     * The NFC controller will be put in a low-power polling mode, allowing the device
-     * to save power in cases where it's "attached" to a tag all the time (e.g. a tag in
-     * car dock).
-     *
-     * Additionally the debounceMs parameter allows you to specify for how long the tag needs
-     * to have gone out of range, before it will be dispatched again.
-     *
-     * Note: the NFC controller typically polls at a pretty slow interval (100 - 500 ms).
-     * This means that if the tag repeatedly goes in and out of range (for example, in
-     * case of a flaky connection), and the controller happens to poll every time the
-     * tag is out of range, it *will* re-dispatch the tag after debounceMs, despite the tag
-     * having been "in range" during the interval.
-     *
-     * Note 2: if a tag with another UID is detected after this API is called, its effect
-     * will be cancelled; if this tag shows up before the amount of time specified in
-     * debounceMs, it will be dispatched again.
-     *
-     * Note 3: some tags have a random UID, in which case this API won't work reliably.
-     *
-     * @param tag        the {@link android.nfc.Tag Tag} to ignore.
-     * @param debounceMs minimum amount of time the tag needs to be out of range before being
-     *                   dispatched again.
-     * @param tagRemovedListener listener to be called when the tag is removed from the field.
-     *                           Note that this will only be called if the tag has been out of range
-     *                           for at least debounceMs, or if another tag came into range before
-     *                           debounceMs. May be null in case you don't want a callback.
-     * @param handler the {@link android.os.Handler Handler} that will be used for delivering
-     *                the callback. if the handler is null, then the thread used for delivering
-     *                the callback is unspecified.
-     * @return false if the tag couldn't be found (or has already gone out of range), true otherwise
-     */
-    public boolean ignore(final Tag tag, int debounceMs,
-                          final OnTagRemovedListener tagRemovedListener, final Handler handler) {
-        ITagRemovedCallback.Stub iListener = null;
-        if (tagRemovedListener != null) {
-            iListener = new ITagRemovedCallback.Stub() {
-                @Override
-                public void onTagRemoved() throws RemoteException {
-                    if (handler != null) {
-                        handler.post(new Runnable() {
-                            @Override
-                            public void run() {
-                                tagRemovedListener.onTagRemoved();
-                            }
-                        });
-                    } else {
-                        tagRemovedListener.onTagRemoved();
-                    }
-                    synchronized (mLock) {
-                        mTagRemovedListener = null;
-                    }
-                }
-            };
-        }
-        synchronized (mLock) {
-            mTagRemovedListener = iListener;
-        }
-        final ITagRemovedCallback.Stub passedListener = iListener;
-        return callServiceReturn(() ->
-                sService.ignore(tag.getServiceHandle(), debounceMs, passedListener), false);
-    }
-
-    /**
-     * Inject a mock NFC tag.<p>
-     * Used for testing purposes.
-     * <p class="note">Requires the
-     * {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
-     * @hide
-     */
-    public void dispatch(Tag tag) {
-        if (tag == null) {
-            throw new NullPointerException("tag cannot be null");
-        }
-        callService(() -> sService.dispatch(tag));
-    }
-
-    /**
-     * Registers a new NFC unlock handler with the NFC service.
-     *
-     * <p />NFC unlock handlers are intended to unlock the keyguard in the presence of a trusted
-     * NFC device. The handler should return true if it successfully authenticates the user and
-     * unlocks the keyguard.
-     *
-     * <p /> The parameter {@code tagTechnologies} determines which Tag technologies will be polled for
-     * at the lockscreen. Polling for less tag technologies reduces latency, and so it is
-     * strongly recommended to only provide the Tag technologies that the handler is expected to
-     * receive. There must be at least one tag technology provided, otherwise the unlock handler
-     * is ignored.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean addNfcUnlockHandler(final NfcUnlockHandler unlockHandler,
-                                       String[] tagTechnologies) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        // If there are no tag technologies, don't bother adding unlock handler
-        if (tagTechnologies.length == 0) {
-            return false;
-        }
-
-        try {
-            synchronized (mLock) {
-                if (mNfcUnlockHandlers.containsKey(unlockHandler)) {
-                    // update the tag technologies
-                    callService(() -> {
-                        sService.removeNfcUnlockHandler(mNfcUnlockHandlers.get(unlockHandler));
-                        mNfcUnlockHandlers.remove(unlockHandler);
-                    });
-                }
-
-                INfcUnlockHandler.Stub iHandler = new INfcUnlockHandler.Stub() {
-                    @Override
-                    public boolean onUnlockAttempted(Tag tag) throws RemoteException {
-                        return unlockHandler.onUnlockAttempted(tag);
-                    }
-                };
-                return callServiceReturn(() -> {
-                        sService.addNfcUnlockHandler(
-                            iHandler, Tag.getTechCodesFromStrings(tagTechnologies));
-                        mNfcUnlockHandlers.put(unlockHandler, iHandler);
-                        return true;
-                    }, false);
-            }
-        } catch (IllegalArgumentException e) {
-            Log.e(TAG, "Unable to register LockscreenDispatch", e);
-            return false;
-        }
-
-    }
-
-    /**
-     * Removes a previously registered unlock handler. Also removes the tag technologies
-     * associated with the removed unlock handler.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean removeNfcUnlockHandler(NfcUnlockHandler unlockHandler) {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        synchronized (mLock) {
-            if (mNfcUnlockHandlers.containsKey(unlockHandler)) {
-                return callServiceReturn(() -> {
-                    sService.removeNfcUnlockHandler(mNfcUnlockHandlers.remove(unlockHandler));
-                    return true;
-                }, false);
-            }
-            return true;
-        }
-    }
-
-    /**
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public INfcAdapterExtras getNfcAdapterExtrasInterface() {
-        if (mContext == null) {
-            throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
-                    + " NFC extras APIs");
-        }
-        return callServiceReturn(() ->
-                sService.getNfcAdapterExtrasInterface(mContext.getPackageName()), null);
-
-    }
-
-    void enforceResumed(Activity activity) {
-        if (!activity.isResumed()) {
-            throw new IllegalStateException("API cannot be called while activity is paused");
-        }
-    }
-
-    int getSdkVersion() {
-        if (mContext == null) {
-            return android.os.Build.VERSION_CODES.GINGERBREAD; // best guess
-        } else {
-            return mContext.getApplicationInfo().targetSdkVersion;
-        }
-    }
-
-    /**
-     * Sets NFC controller always on feature.
-     * <p>This API is for the NFCC internal state management. It allows to discriminate
-     * the controller function from the NFC function by keeping the NFC controller on without
-     * any NFC RF enabled if necessary.
-     * <p>This call is asynchronous. Register a listener {@link ControllerAlwaysOnListener}
-     * by {@link #registerControllerAlwaysOnListener} to find out when the operation is
-     * complete.
-     * <p>If this returns true, then either NFCC always on state has been set based on the value,
-     * or a {@link ControllerAlwaysOnListener#onControllerAlwaysOnChanged(boolean)} will be invoked
-     * to indicate the state change.
-     * If this returns false, then there is some problem that prevents an attempt to turn NFCC
-     * always on.
-     * @param value if true the NFCC will be kept on (with no RF enabled if NFC adapter is
-     * disabled), if false the NFCC will follow completely the Nfc adapter state.
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     * are unavailable
-     * @return true if feature is supported by the device and operation has been initiated,
-     * false if the feature is not supported by the device.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public boolean setControllerAlwaysOn(boolean value) {
-        if (!sHasNfcFeature && !sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        int mode = value ? CONTROLLER_ALWAYS_ON_MODE_DEFAULT : CONTROLLER_ALWAYS_ON_DISABLE;
-        try {
-            callService(() -> sService.setControllerAlwaysOn(mode));
-        } catch (UnsupportedOperationException e) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Checks NFC controller always on feature is enabled.
-     *
-     * @return True if NFC controller always on is enabled, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     * are unavailable
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public boolean isControllerAlwaysOn() {
-        return callServiceReturn(() ->  sService.isControllerAlwaysOn(), false);
-
-    }
-
-    /**
-     * Checks if the device supports NFC controller always on functionality.
-     *
-     * @return True if device supports NFC controller always on, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC,
-     * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     * are unavailable
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public boolean isControllerAlwaysOnSupported() {
-        if (!sHasNfcFeature && !sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.isControllerAlwaysOnSupported(), false);
-
-    }
-
-    /**
-     * Register a {@link ControllerAlwaysOnListener} to listen for NFC controller always on
-     * state changes
-     * <p>The provided listener will be invoked by the given {@link Executor}.
-     *
-     * @param executor an {@link Executor} to execute given listener
-     * @param listener user implementation of the {@link ControllerAlwaysOnListener}
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public void registerControllerAlwaysOnListener(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull ControllerAlwaysOnListener listener) {
-        mControllerAlwaysOnListener.register(executor, listener);
-    }
-
-    /**
-     * Unregister the specified {@link ControllerAlwaysOnListener}
-     * <p>The same {@link ControllerAlwaysOnListener} object used when calling
-     * {@link #registerControllerAlwaysOnListener(Executor, ControllerAlwaysOnListener)}
-     * must be used.
-     *
-     * <p>Listeners are automatically unregistered when application process goes away
-     *
-     * @param listener user implementation of the {@link ControllerAlwaysOnListener}
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public void unregisterControllerAlwaysOnListener(
-            @NonNull ControllerAlwaysOnListener listener) {
-        mControllerAlwaysOnListener.unregister(listener);
-    }
-
-
-    /**
-     * Sets whether we dispatch NFC Tag intents to the package.
-     *
-     * <p>{@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
-     * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if its package is
-     * disallowed.
-     * <p>An app is added to the preference list with the allowed flag set to {@code true}
-     * when a Tag intent is dispatched to the package for the first time. This API is called
-     * by settings to note that the user wants to change this default preference.
-     *
-     * @param userId the user to whom this package name will belong to
-     * @param pkg the full name (i.e. com.google.android.tag) of the package that will be added to
-     * the preference list
-     * @param allow {@code true} to allow dispatching Tag intents to the package's activity,
-     * {@code false} otherwise
-     * @return the {@link #TagIntentAppPreferenceResult} value
-     * @throws UnsupportedOperationException if {@link isTagIntentAppPreferenceSupported} returns
-     * {@code false}
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @TagIntentAppPreferenceResult
-    public int setTagIntentAppPreferenceForUser(@UserIdInt int userId,
-                @NonNull String pkg, boolean allow) {
-        Objects.requireNonNull(pkg, "pkg cannot be null");
-        if (!isTagIntentAppPreferenceSupported()) {
-            Log.e(TAG, "TagIntentAppPreference is not supported");
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->
-                sService.setTagIntentAppPreferenceForUser(userId, pkg, allow),
-                        TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE);
-    }
-
-
-    /**
-     * Get the Tag dispatch preference list of the UserId.
-     *
-     * <p>This returns a mapping of package names for this user id to whether we dispatch Tag
-     * intents to the package. {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
-     * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if its package is
-     * mapped to {@code false}.
-     * <p>There are three different possible cases:
-     * <p>A package not being in the preference list.
-     * It does not contain any Tag intent filters or the user never triggers a Tag detection that
-     * matches the intent filter of the package.
-     * <p>A package being mapped to {@code true}.
-     * When a package has been launched by a tag detection for the first time, the package name is
-     * put to the map and by default mapped to {@code true}. The package will receive Tag intents as
-     * usual.
-     * <p>A package being mapped to {@code false}.
-     * The user chooses to disable this package and it will not receive any Tag intents anymore.
-     *
-     * @param userId the user to whom this preference list will belong to
-     * @return a map of the UserId which indicates the mapping from package name to
-     * boolean(allow status), otherwise return an empty map
-     * @throws UnsupportedOperationException if {@link isTagIntentAppPreferenceSupported} returns
-     * {@code false}
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @NonNull
-    public Map<String, Boolean> getTagIntentAppPreferenceForUser(@UserIdInt int userId) {
-        if (!isTagIntentAppPreferenceSupported()) {
-            Log.e(TAG, "TagIntentAppPreference is not supported");
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn( () ->
-            sService.getTagIntentAppPreferenceForUser(userId), Collections.emptyMap());
-    }
-
-    /**
-     * Checks if the device supports Tag Intent App Preference functionality.
-     *
-     * When supported, {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
-     * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if
-     * {@link isTagIntentAllowed} returns {@code false}.
-     *
-     * @return {@code true} if the device supports Tag application preference, {@code false}
-     * otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
-     */
-    @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
-    public boolean isTagIntentAppPreferenceSupported() {
-        if (!sHasNfcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.isTagIntentAppPreferenceSupported(), false);
-    }
-
-   /**
-     * Notifies the system of a new polling loop.
-     *
-     * @param frame is the new frame.
-     *
-     * @hide
-     */
-    @TestApi
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public void notifyPollingLoop(@NonNull PollingFrame pollingFrame) {
-        callService(() ->  sService.notifyPollingLoop(pollingFrame));
-    }
-
-
-   /**
-     * Notifies the system of new HCE data for tests.
-     *
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public void notifyTestHceData(int technology, byte[] data) {
-        callService(() ->  sService.notifyTestHceData(technology, data));
-    }
-
-    /** @hide */
-    interface ServiceCall {
-        void call() throws RemoteException;
-    }
-    /** @hide */
-    static void callService(ServiceCall call) {
-        try {
-            if (sService == null) {
-                attemptDeadServiceRecovery(new RemoteException("NFC Service is null"));
-            }
-            call.call();
-        } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
-            try {
-                call.call();
-            } catch (RemoteException ee) {
-                ee.rethrowAsRuntimeException();
-            }
-        }
-    }
-    /** @hide */
-    interface ServiceCallReturn<T> {
-        T call() throws RemoteException;
-    }
-    /** @hide */
-    static <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) {
-        try {
-            if (sService == null) {
-                attemptDeadServiceRecovery(new RemoteException("NFC Service is null"));
-            }
-            return call.call();
-        } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
-            // Try one more time
-            try {
-                return call.call();
-            } catch (RemoteException ee) {
-                ee.rethrowAsRuntimeException();
-            }
-        }
-        return defaultReturn;
-    }
-
-   /**
-     * Notifies the system of a an HCE session being deactivated.
-     *     *
-     * @hide
-     */
-    @TestApi
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public void notifyHceDeactivated() {
-        callService(() ->  sService.notifyHceDeactivated());
-    }
-
-    /**
-     * Sets NFC charging feature.
-     * <p>This API is for the Settings application.
-     * @return True if successful
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean setWlcEnabled(boolean enable) {
-        if (!sHasNfcWlcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.setWlcEnabled(enable), false);
-    }
-
-    /**
-     * Checks NFC charging feature is enabled.
-     *
-     * @return True if NFC charging is enabled, false otherwise
-     * @throws UnsupportedOperationException if FEATURE_NFC_CHARGING
-     * is unavailable
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-    public boolean isWlcEnabled() {
-        if (!sHasNfcWlcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.isWlcEnabled(), false);
-
-    }
-
-    /**
-     * A listener to be invoked when NFC controller always on state changes.
-     * <p>Register your {@code ControllerAlwaysOnListener} implementation with {@link
-     * NfcAdapter#registerWlcStateListener} and disable it with {@link
-     * NfcAdapter#unregisterWlcStateListenerListener}.
-     * @see #registerWlcStateListener
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-    public interface WlcStateListener {
-        /**
-         * Called on NFC WLC state changes
-         */
-        void onWlcStateChanged(@NonNull WlcListenerDeviceInfo wlcListenerDeviceInfo);
-    }
-
-    /**
-     * Register a {@link WlcStateListener} to listen for NFC WLC state changes
-     * <p>The provided listener will be invoked by the given {@link Executor}.
-     *
-     * @param executor an {@link Executor} to execute given listener
-     * @param listener user implementation of the {@link WlcStateListener}
-     * @throws UnsupportedOperationException if FEATURE_NFC_CHARGING
-     * is unavailable
-     *
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-    public void registerWlcStateListener(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull WlcStateListener listener) {
-        if (!sHasNfcWlcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        mNfcWlcStateListener.register(executor, listener);
-    }
-
-    /**
-     * Unregister the specified {@link WlcStateListener}
-     * <p>The same {@link WlcStateListener} object used when calling
-     * {@link #registerWlcStateListener(Executor, WlcStateListener)}
-     * must be used.
-     *
-     * <p>Listeners are automatically unregistered when application process goes away
-     *
-     * @param listener user implementation of the {@link WlcStateListener}a
-     * @throws UnsupportedOperationException if FEATURE_NFC_CHARGING
-     * is unavailable
-     *
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-    public void unregisterWlcStateListener(
-            @NonNull WlcStateListener listener) {
-        if (!sHasNfcWlcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        mNfcWlcStateListener.unregister(listener);
-    }
-
-    /**
-     * Returns information on the NFC charging listener device
-     *
-     * @return Information on the NFC charging listener device
-     * @throws UnsupportedOperationException if FEATURE_NFC_CHARGING
-     * is unavailable
-     */
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-    @Nullable
-    public WlcListenerDeviceInfo getWlcListenerDeviceInfo() {
-        if (!sHasNfcWlcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        return callServiceReturn(() ->  sService.getWlcListenerDeviceInfo(), null);
-
-    }
-
-    /**
-     * Vendor NCI command success.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    public static final int SEND_VENDOR_NCI_STATUS_SUCCESS = 0;
-    /**
-     * Vendor NCI command rejected.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    public static final int SEND_VENDOR_NCI_STATUS_REJECTED = 1;
-    /**
-     * Vendor NCI command corrupted.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    public static final int SEND_VENDOR_NCI_STATUS_MESSAGE_CORRUPTED  = 2;
-    /**
-     * Vendor NCI command failed with unknown reason.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    public static final int SEND_VENDOR_NCI_STATUS_FAILED = 3;
-
-    /**
-     * @hide
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            SEND_VENDOR_NCI_STATUS_SUCCESS,
-            SEND_VENDOR_NCI_STATUS_REJECTED,
-            SEND_VENDOR_NCI_STATUS_MESSAGE_CORRUPTED,
-            SEND_VENDOR_NCI_STATUS_FAILED,
-    })
-    @interface SendVendorNciStatus {}
-
-    /**
-     * Message Type for NCI Command.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    public static final int MESSAGE_TYPE_COMMAND = 1;
-
-    /**
-     * @hide
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            MESSAGE_TYPE_COMMAND,
-    })
-    @interface MessageType {}
-
-    /**
-     * Send Vendor specific Nci Messages with custom message type.
-     *
-     * The format of the NCI messages are defined in the NCI specification. The platform is
-     * responsible for fragmenting the payload if necessary.
-     *
-     * Note that mt (message type) is added at the beginning of method parameters as it is more
-     * distinctive than other parameters and was requested from vendor.
-     *
-     * @param mt message Type of the command
-     * @param gid group ID of the command. This needs to be one of the vendor reserved GIDs from
-     *            the NCI specification
-     * @param oid opcode ID of the command. This is left to the OEM / vendor to decide
-     * @param payload containing vendor Nci message payload
-     * @return message send status
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public @SendVendorNciStatus int sendVendorNciMessage(@MessageType int mt,
-            @IntRange(from = 0, to = 15) int gid, @IntRange(from = 0) int oid,
-            @NonNull byte[] payload) {
-        Objects.requireNonNull(payload, "Payload must not be null");
-        return callServiceReturn(() ->  sService.sendVendorNciMessage(mt, gid, oid, payload),
-                SEND_VENDOR_NCI_STATUS_FAILED);
-    }
-
-    /**
-     * Register an {@link NfcVendorNciCallback} to listen for Nfc vendor responses and notifications
-     * <p>The provided callback will be invoked by the given {@link Executor}.
-     *
-     * <p>When first registering a callback, the callbacks's
-     * {@link NfcVendorNciCallback#onVendorNciCallBack(byte[])} is immediately invoked to
-     * notify the vendor notification.
-     *
-     * @param executor an {@link Executor} to execute given callback
-     * @param callback user implementation of the {@link NfcVendorNciCallback}
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void registerNfcVendorNciCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull NfcVendorNciCallback callback) {
-        mNfcVendorNciCallbackListener.register(executor, callback);
-    }
-
-    /**
-     * Unregister the specified {@link NfcVendorNciCallback}
-     *
-     * <p>The same {@link NfcVendorNciCallback} object used when calling
-     * {@link #registerNfcVendorNciCallback(Executor, NfcVendorNciCallback)} must be used.
-     *
-     * <p>Callbacks are automatically unregistered when application process goes away
-     *
-     * @param callback user implementation of the {@link NfcVendorNciCallback}
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void unregisterNfcVendorNciCallback(@NonNull NfcVendorNciCallback callback) {
-        mNfcVendorNciCallbackListener.unregister(callback);
-    }
-
-    /**
-     * Interface for receiving vendor NCI responses and notifications.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-    public interface NfcVendorNciCallback {
-        /**
-         * Invoked when a vendor specific NCI response is received.
-         *
-         * @param gid group ID of the command. This needs to be one of the vendor reserved GIDs from
-         *            the NCI specification.
-         * @param oid opcode ID of the command. This is left to the OEM / vendor to decide.
-         * @param payload containing vendor Nci message payload.
-         */
-        @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-        void onVendorNciResponse(
-                @IntRange(from = 0, to = 15) int gid, int oid, @NonNull byte[] payload);
-
-        /**
-         * Invoked when a vendor specific NCI notification is received.
-         *
-         * @param gid group ID of the command. This needs to be one of the vendor reserved GIDs from
-         *            the NCI specification.
-         * @param oid opcode ID of the command. This is left to the OEM / vendor to decide.
-         * @param payload containing vendor Nci message payload.
-         */
-        @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
-        void onVendorNciNotification(
-                @IntRange(from = 9, to = 15) int gid, int oid, @NonNull byte[] payload);
-    }
-
-    /**
-     * Used by data migration to indicate data migration is in progrerss or not.
-     *
-     * Note: This is @hide intentionally since the client is inside the NFC apex.
-     * @param inProgress true if migration is in progress, false once done.
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void indicateDataMigration(boolean inProgress) {
-        callService(() -> sService.indicateDataMigration(inProgress, mContext.getPackageName()));
-    }
-
-    /**
-     * Returns an instance of {@link NfcOemExtension} associated with {@link NfcAdapter} instance.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @NonNull public NfcOemExtension getNfcOemExtension() {
-        synchronized (sLock) {
-            if (!sHasNfcFeature) {
-                throw new UnsupportedOperationException();
-            }
-        }
-        return mNfcOemExtension;
-    }
-
-    /**
-     * Activity action: Bring up the settings page that allows the user to enable or disable tag
-     * intent reception for apps.
-     *
-     * <p>This will direct user to the settings page shows a list that asks users whether
-     * they want to allow or disallow the package to start an activity when a tag is discovered.
-     *
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
-    public static final String ACTION_CHANGE_TAG_INTENT_PREFERENCE =
-            "android.nfc.action.CHANGE_TAG_INTENT_PREFERENCE";
-
-    /**
-     * Checks whether the user has disabled the calling app from receiving NFC tag intents.
-     *
-     * <p>This method checks whether the caller package name is either not present in the user
-     * disabled list or is explicitly allowed by the user.
-     *
-     * @return {@code true} if an app is either not present in the list or is added to the list
-     * with the flag set to {@code true}. Otherwise, it returns {@code false}.
-     * It also returns {@code true} if {@link isTagIntentAppPreferenceSupported} returns
-     * {@code false}.
-     *
-     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
-    public boolean isTagIntentAllowed() {
-        if (!sHasNfcFeature) {
-            throw new UnsupportedOperationException();
-        }
-        if (!isTagIntentAppPreferenceSupported()) {
-            return true;
-        }
-        return callServiceReturn(() ->  sService.isTagIntentAllowed(mContext.getPackageName(),
-                UserHandle.myUserId()), false);
-    }
-}
diff --git a/nfc/java/android/nfc/NfcAntennaInfo.aidl b/nfc/java/android/nfc/NfcAntennaInfo.aidl
deleted file mode 100644
index d5e79fc..0000000
--- a/nfc/java/android/nfc/NfcAntennaInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.nfc;
-
-parcelable NfcAntennaInfo;
diff --git a/nfc/java/android/nfc/NfcAntennaInfo.java b/nfc/java/android/nfc/NfcAntennaInfo.java
deleted file mode 100644
index c57b2e0..0000000
--- a/nfc/java/android/nfc/NfcAntennaInfo.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * Contains information on all available Nfc
- * antennas on an Android device as well as information
- * on the device itself in relation positioning of the
- * antennas.
- */
-public final class NfcAntennaInfo implements Parcelable {
-    // Width of the device in millimeters.
-    private final int mDeviceWidth;
-    // Height of the device in millimeters.
-    private final int mDeviceHeight;
-    // Whether the device is foldable.
-    private final boolean mDeviceFoldable;
-    // All available Nfc Antennas on the device.
-    private final List<AvailableNfcAntenna> mAvailableNfcAntennas;
-
-    public NfcAntennaInfo(int deviceWidth, int deviceHeight, boolean deviceFoldable,
-            @NonNull List<AvailableNfcAntenna> availableNfcAntennas) {
-        this.mDeviceWidth = deviceWidth;
-        this.mDeviceHeight = deviceHeight;
-        this.mDeviceFoldable = deviceFoldable;
-        this.mAvailableNfcAntennas = availableNfcAntennas;
-    }
-
-    /**
-     * Width of the device in millimeters.
-     */
-    public int getDeviceWidth() {
-        return mDeviceWidth;
-    }
-
-    /**
-     * Height of the device in millimeters.
-     */
-    public int getDeviceHeight() {
-        return mDeviceHeight;
-    }
-
-    /**
-     * Whether the device is foldable. When the device is foldable,
-     * the 0, 0 is considered to be top-left when the device is unfolded and
-     * the screens are facing the user. For non-foldable devices 0, 0
-     * is top-left when the user is facing the screen.
-     */
-    public boolean isDeviceFoldable() {
-        return mDeviceFoldable;
-    }
-
-    /**
-     * Get all NFC antennas that exist on the device.
-     */
-    @NonNull
-    public List<AvailableNfcAntenna> getAvailableNfcAntennas() {
-        return mAvailableNfcAntennas;
-    }
-
-    private NfcAntennaInfo(Parcel in) {
-        this.mDeviceWidth = in.readInt();
-        this.mDeviceHeight = in.readInt();
-        this.mDeviceFoldable = in.readByte() != 0;
-        this.mAvailableNfcAntennas = new ArrayList<>();
-        in.readTypedList(this.mAvailableNfcAntennas,
-                AvailableNfcAntenna.CREATOR);
-    }
-
-    public static final @NonNull Parcelable.Creator<NfcAntennaInfo> CREATOR =
-            new Parcelable.Creator<NfcAntennaInfo>() {
-        @Override
-        public NfcAntennaInfo createFromParcel(Parcel in) {
-            return new NfcAntennaInfo(in);
-        }
-
-        @Override
-        public NfcAntennaInfo[] newArray(int size) {
-            return new NfcAntennaInfo[size];
-        }
-    };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mDeviceWidth);
-        dest.writeInt(mDeviceHeight);
-        dest.writeByte((byte) (mDeviceFoldable ? 1 : 0));
-        dest.writeTypedList(mAvailableNfcAntennas, 0);
-    }
-}
diff --git a/nfc/java/android/nfc/NfcControllerAlwaysOnListener.java b/nfc/java/android/nfc/NfcControllerAlwaysOnListener.java
deleted file mode 100644
index 6ae58fd..0000000
--- a/nfc/java/android/nfc/NfcControllerAlwaysOnListener.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.nfc.NfcAdapter.ControllerAlwaysOnListener;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * @hide
- */
-public class NfcControllerAlwaysOnListener extends INfcControllerAlwaysOnListener.Stub {
-    private static final String TAG = NfcControllerAlwaysOnListener.class.getSimpleName();
-
-    private final INfcAdapter mAdapter;
-
-    private final Map<ControllerAlwaysOnListener, Executor> mListenerMap = new HashMap<>();
-
-    private boolean mCurrentState = false;
-    private boolean mIsRegistered = false;
-
-    public NfcControllerAlwaysOnListener(@NonNull INfcAdapter adapter) {
-        mAdapter = adapter;
-    }
-
-    /**
-     * Register a {@link ControllerAlwaysOnListener} with this
-     * {@link NfcControllerAlwaysOnListener}
-     *
-     * @param executor an {@link Executor} to execute given listener
-     * @param listener user implementation of the {@link ControllerAlwaysOnListener}
-     */
-    public void register(@NonNull Executor executor,
-            @NonNull ControllerAlwaysOnListener listener) {
-        try {
-            if (!mAdapter.isControllerAlwaysOnSupported()) {
-                return;
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to register");
-            return;
-        }
-        synchronized (this) {
-            if (mListenerMap.containsKey(listener)) {
-                return;
-            }
-
-            mListenerMap.put(listener, executor);
-            if (!mIsRegistered) {
-                try {
-                    mAdapter.registerControllerAlwaysOnListener(this);
-                    mIsRegistered = true;
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to register");
-                }
-            }
-        }
-    }
-
-    /**
-     * Unregister the specified {@link ControllerAlwaysOnListener}
-     *
-     * @param listener user implementation of the {@link ControllerAlwaysOnListener}
-     */
-    public void unregister(@NonNull ControllerAlwaysOnListener listener) {
-        try {
-            if (!mAdapter.isControllerAlwaysOnSupported()) {
-                return;
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to unregister");
-            return;
-        }
-        synchronized (this) {
-            if (!mListenerMap.containsKey(listener)) {
-                return;
-            }
-
-            mListenerMap.remove(listener);
-
-            if (mListenerMap.isEmpty() && mIsRegistered) {
-                try {
-                    mAdapter.unregisterControllerAlwaysOnListener(this);
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to unregister");
-                }
-                mIsRegistered = false;
-            }
-        }
-    }
-
-    private void sendCurrentState(@NonNull ControllerAlwaysOnListener listener) {
-        synchronized (this) {
-            Executor executor = mListenerMap.get(listener);
-
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                executor.execute(() -> listener.onControllerAlwaysOnChanged(
-                        mCurrentState));
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    @Override
-    public void onControllerAlwaysOnChanged(boolean isEnabled) {
-        synchronized (this) {
-            mCurrentState = isEnabled;
-            for (ControllerAlwaysOnListener cb : mListenerMap.keySet()) {
-                sendCurrentState(cb);
-            }
-        }
-    }
-}
-
diff --git a/nfc/java/android/nfc/NfcEvent.java b/nfc/java/android/nfc/NfcEvent.java
deleted file mode 100644
index aff4f52..0000000
--- a/nfc/java/android/nfc/NfcEvent.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2011 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 android.nfc;
-
-/**
- * Wraps information associated with any NFC event.
- *
- * <p>Immutable object, with direct access to the (final) fields.
- *
- * <p>An {@link NfcEvent} object is usually included in callbacks from
- * {@link NfcAdapter}. Check the documentation of the callback to see
- * which fields may be set.
- *
- * <p>This wrapper object is used (instead of parameters
- * in the callback) because it allows new fields to be added without breaking
- * API compatibility.
- *
- * @see NfcAdapter.OnNdefPushCompleteCallback#onNdefPushComplete
- * @see NfcAdapter.CreateNdefMessageCallback#createNdefMessage
- */
-public final class NfcEvent {
-    /**
-     * The {@link NfcAdapter} associated with the NFC event.
-     */
-    public final NfcAdapter nfcAdapter;
-
-    /**
-     * The major LLCP version number of the peer associated with the NFC event.
-     */
-    public final int peerLlcpMajorVersion;
-
-    /**
-     * The minor LLCP version number of the peer associated with the NFC event.
-     */
-    public final int peerLlcpMinorVersion;
-
-    NfcEvent(NfcAdapter nfcAdapter, byte peerLlcpVersion) {
-        this.nfcAdapter = nfcAdapter;
-        this.peerLlcpMajorVersion = (peerLlcpVersion & 0xF0) >> 4;
-        this.peerLlcpMinorVersion = peerLlcpVersion & 0x0F;
-    }
-}
diff --git a/nfc/java/android/nfc/NfcFrameworkInitializer.java b/nfc/java/android/nfc/NfcFrameworkInitializer.java
deleted file mode 100644
index 1ab8a1e..0000000
--- a/nfc/java/android/nfc/NfcFrameworkInitializer.java
+++ /dev/null
@@ -1,71 +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 android.nfc;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.app.SystemServiceRegistry;
-import android.content.Context;
-
-/**
- * Class for performing registration for Nfc service.
- *
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public class NfcFrameworkInitializer {
-    private NfcFrameworkInitializer() {}
-
-    private static volatile NfcServiceManager sNfcServiceManager;
-
-    /**
-     * Sets an instance of {@link NfcServiceManager} that allows
-     * the nfc mainline module to register/obtain nfc binder services. This is called
-     * by the platform during the system initialization.
-     *
-     * @param nfcServiceManager instance of {@link NfcServiceManager} that allows
-     * the nfc mainline module to register/obtain nfcd binder services.
-     */
-    public static void setNfcServiceManager(
-            @NonNull NfcServiceManager nfcServiceManager) {
-        if (sNfcServiceManager != null) {
-            throw new IllegalStateException("setNfcServiceManager called twice!");
-        }
-
-        if (nfcServiceManager == null) {
-            throw new IllegalArgumentException("nfcServiceManager must not be null");
-        }
-
-        sNfcServiceManager = nfcServiceManager;
-    }
-
-    /** @hide */
-    public static NfcServiceManager getNfcServiceManager() {
-        return sNfcServiceManager;
-    }
-
-    /**
-     * Called by {@link SystemServiceRegistry}'s static initializer and registers NFC service
-     * to {@link Context}, so that {@link Context#getSystemService} can return them.
-     *
-     * @throws IllegalStateException if this is called from anywhere besides
-     * {@link SystemServiceRegistry}
-     */
-    public static void registerServiceWrappers() {
-        SystemServiceRegistry.registerContextAwareService(Context.NFC_SERVICE,
-                NfcManager.class, context -> new NfcManager(context));
-    }
-}
diff --git a/nfc/java/android/nfc/NfcManager.java b/nfc/java/android/nfc/NfcManager.java
deleted file mode 100644
index 644e312..0000000
--- a/nfc/java/android/nfc/NfcManager.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc;
-
-import android.annotation.SystemService;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.os.Build;
-
-/**
- * High level manager used to obtain an instance of an {@link NfcAdapter}.
- * <p>
- * Use {@link android.content.Context#getSystemService(java.lang.String)}
- * with {@link Context#NFC_SERVICE} to create an {@link NfcManager},
- * then call {@link #getDefaultAdapter} to obtain the {@link NfcAdapter}.
- * <p>
- * Alternately, you can just call the static helper
- * {@link NfcAdapter#getDefaultAdapter(android.content.Context)}.
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about using NFC, read the
- * <a href="{@docRoot}guide/topics/nfc/index.html">Near Field Communication</a> developer guide.</p>
- * </div>
- *
- * @see NfcAdapter#getDefaultAdapter(android.content.Context)
- */
-@SystemService(Context.NFC_SERVICE)
-public final class NfcManager {
-    private final NfcAdapter mAdapter;
-
-    /**
-     * @hide
-     */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    public NfcManager(Context context) {
-        NfcAdapter adapter;
-        context = context.getApplicationContext();
-        if (context == null) {
-            throw new IllegalArgumentException(
-                    "context not associated with any application (using a mock context?)");
-        }
-        try {
-            adapter = NfcAdapter.getNfcAdapter(context);
-        } catch (UnsupportedOperationException e) {
-            adapter = null;
-        }
-        mAdapter = adapter;
-    }
-
-    /**
-     * Get the default NFC Adapter for this device.
-     *
-     * @return the default NFC Adapter
-     */
-    public NfcAdapter getDefaultAdapter() {
-        return mAdapter;
-    }
-}
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
deleted file mode 100644
index 1fc0786..0000000
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ /dev/null
@@ -1,1248 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import static android.nfc.cardemulation.CardEmulation.PROTOCOL_AND_TECHNOLOGY_ROUTE_DH;
-import static android.nfc.cardemulation.CardEmulation.PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE;
-import static android.nfc.cardemulation.CardEmulation.PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC;
-import static android.nfc.cardemulation.CardEmulation.routeIntToString;
-
-import android.Manifest;
-import android.annotation.CallbackExecutor;
-import android.annotation.DurationMillisLong;
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.nfc.cardemulation.ApduServiceInfo;
-import android.nfc.cardemulation.CardEmulation;
-import android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.se.omapi.Reader;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Supplier;
-
-/**
- * Used for OEM extension APIs.
- * This class holds all the APIs and callbacks defined for OEMs/vendors to extend the NFC stack
- * for their proprietary features.
- *
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public final class NfcOemExtension {
-    private static final String TAG = "NfcOemExtension";
-    private static final int OEM_EXTENSION_RESPONSE_THRESHOLD_MS = 2000;
-    private static final int TYPE_TECHNOLOGY = 0;
-    private static final int TYPE_PROTOCOL = 1;
-    private static final int TYPE_AID = 2;
-    private static final int TYPE_SYSTEMCODE = 3;
-
-    private final NfcAdapter mAdapter;
-    private final NfcOemExtensionCallback mOemNfcExtensionCallback;
-    private boolean mIsRegistered = false;
-    private final Map<Callback, Executor> mCallbackMap = new HashMap<>();
-    private final Context mContext;
-    private final Object mLock = new Object();
-    private boolean mCardEmulationActivated = false;
-    private boolean mRfFieldActivated = false;
-    private boolean mRfDiscoveryStarted = false;
-    private boolean mEeListenActivated = false;
-
-    /**
-     * Broadcast Action: Sent on NFC stack initialization when NFC OEM extensions are enabled.
-     * <p> OEM extension modules should use this intent to start their extension service </p>
-     * @hide
-     */
-    public static final String ACTION_OEM_EXTENSION_INIT = "android.nfc.action.OEM_EXTENSION_INIT";
-
-    /**
-     * Mode Type for {@link #setControllerAlwaysOnMode(int)}.
-     * Enables the controller in default mode when NFC is disabled (existing API behavior).
-     * works same as {@link NfcAdapter#setControllerAlwaysOn(boolean)}.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int ENABLE_DEFAULT = NfcAdapter.CONTROLLER_ALWAYS_ON_MODE_DEFAULT;
-
-    /**
-     * Mode Type for {@link #setControllerAlwaysOnMode(int)}.
-     * Enables the controller in transparent mode when NFC is disabled.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int ENABLE_TRANSPARENT = 2;
-
-    /**
-     * Mode Type for {@link #setControllerAlwaysOnMode(int)}.
-     * Enables the controller and initializes and enables the EE subsystem when NFC is disabled.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int ENABLE_EE = 3;
-
-    /**
-     * Mode Type for {@link #setControllerAlwaysOnMode(int)}.
-     * Disable the Controller Always On Mode.
-     * works same as {@link NfcAdapter#setControllerAlwaysOn(boolean)}.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int DISABLE = NfcAdapter.CONTROLLER_ALWAYS_ON_DISABLE;
-
-    /**
-     * Possible controller modes for {@link #setControllerAlwaysOnMode(int)}.
-     *
-     * @hide
-     */
-    @IntDef(prefix = { "" }, value = {
-        ENABLE_DEFAULT,
-        ENABLE_TRANSPARENT,
-        ENABLE_EE,
-        DISABLE,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ControllerMode{}
-
-    /**
-     * Technology Type for {@link #getActiveNfceeList()}.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int NFCEE_TECH_NONE = 0;
-
-    /**
-     * Technology Type for {@link #getActiveNfceeList()}.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int NFCEE_TECH_A = 1;
-
-    /**
-     * Technology Type for {@link #getActiveNfceeList()}.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int NFCEE_TECH_B = 1 << 1;
-
-    /**
-     * Technology Type for {@link #getActiveNfceeList()}.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int NFCEE_TECH_F = 1 << 2;
-
-    /**
-     * Nfc technology flags for {@link #getActiveNfceeList()}.
-     *
-     * @hide
-     */
-    @IntDef(flag = true, value = {
-        NFCEE_TECH_NONE,
-        NFCEE_TECH_A,
-        NFCEE_TECH_B,
-        NFCEE_TECH_F,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface NfceeTechnology {}
-
-    /**
-     * Event that Host Card Emulation is activated.
-     */
-    public static final int HCE_ACTIVATE = 1;
-    /**
-     * Event that some data is transferred in Host Card Emulation.
-     */
-    public static final int HCE_DATA_TRANSFERRED = 2;
-    /**
-     * Event that Host Card Emulation is deactivated.
-     */
-    public static final int HCE_DEACTIVATE = 3;
-    /**
-     * Possible events from {@link Callback#onHceEventReceived}.
-     *
-     * @hide
-     */
-    @IntDef(value = {
-            HCE_ACTIVATE,
-            HCE_DATA_TRANSFERRED,
-            HCE_DEACTIVATE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface HostCardEmulationAction {}
-
-    /**
-     * Status code returned when the polling state change request succeeded.
-     * @see #pausePolling()
-     * @see #resumePolling()
-     */
-    public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1;
-    /**
-     * Status code returned when the polling state change request is already in
-     * required state.
-     * @see #pausePolling()
-     * @see #resumePolling()
-     */
-    public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2;
-    /**
-     * Possible status codes for {@link #pausePolling()} and
-     * {@link #resumePolling()}.
-     * @hide
-     */
-    @IntDef(value = {
-            POLLING_STATE_CHANGE_SUCCEEDED,
-            POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface PollingStateChangeStatusCode {}
-
-    /**
-     * Status OK
-     */
-    public static final int STATUS_OK = 0;
-    /**
-     * Status unknown error
-     */
-    public static final int STATUS_UNKNOWN_ERROR = 1;
-
-    /**
-     * Status codes passed to OEM extension callbacks.
-     *
-     * @hide
-     */
-    @IntDef(value = {
-            STATUS_OK,
-            STATUS_UNKNOWN_ERROR
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface StatusCode {}
-
-    /**
-     * Routing commit succeeded.
-     */
-    public static final int COMMIT_ROUTING_STATUS_OK = 0;
-    /**
-     * Routing commit failed.
-     */
-    public static final int COMMIT_ROUTING_STATUS_FAILED = 3;
-    /**
-     * Routing commit failed due to the update is in progress.
-     */
-    public static final int COMMIT_ROUTING_STATUS_FAILED_UPDATE_IN_PROGRESS = 6;
-
-    /**
-     * Status codes returned when calling {@link #forceRoutingTableCommit()}
-     * @hide
-     */
-    @IntDef(prefix = "COMMIT_ROUTING_STATUS_", value = {
-            COMMIT_ROUTING_STATUS_OK,
-            COMMIT_ROUTING_STATUS_FAILED,
-            COMMIT_ROUTING_STATUS_FAILED_UPDATE_IN_PROGRESS,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CommitRoutingStatusCode {}
-    /**
-     * Interface for Oem extensions for NFC.
-     */
-    public interface Callback {
-        /**
-         * Notify Oem to tag is connected or not
-         * ex - if tag is connected  notify cover and Nfctest app if app is in testing mode
-         *
-         * @param connected status of the tag true if tag is connected otherwise false
-         */
-        void onTagConnected(boolean connected);
-
-        /**
-         * Update the Nfc Adapter State
-         * @param state new state that need to be updated
-         */
-        void onStateUpdated(@NfcAdapter.AdapterState int state);
-        /**
-         * Check if NfcService apply routing method need to be skipped for
-         * some feature.
-         * @param isSkipped The {@link Consumer} to be completed. If apply routing can be skipped,
-         *                  the {@link Consumer#accept(Object)} should be called with
-         *                  {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
-         */
-        void onApplyRouting(@NonNull Consumer<Boolean> isSkipped);
-        /**
-         * Check if NfcService ndefRead method need to be skipped To skip
-         * and start checking for presence of tag
-         * @param isSkipped The {@link Consumer} to be completed. If Ndef read can be skipped,
-         *                  the {@link Consumer#accept(Object)} should be called with
-         *                  {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
-         */
-        void onNdefRead(@NonNull Consumer<Boolean> isSkipped);
-        /**
-         * Method to check if Nfc is allowed to be enabled by OEMs.
-         * @param isAllowed The {@link Consumer} to be completed. If enabling NFC is allowed,
-         *                  the {@link Consumer#accept(Object)} should be called with
-         *                  {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
-         * false if NFC cannot be enabled at this time.
-         */
-        void onEnableRequested(@NonNull Consumer<Boolean> isAllowed);
-        /**
-         * Method to check if Nfc is allowed to be disabled by OEMs.
-         * @param isAllowed The {@link Consumer} to be completed. If disabling NFC is allowed,
-         *                  the {@link Consumer#accept(Object)} should be called with
-         *                  {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
-         * false if NFC cannot be disabled at this time.
-         */
-        void onDisableRequested(@NonNull Consumer<Boolean> isAllowed);
-
-        /**
-         * Callback to indicate that Nfc starts to boot.
-         */
-        void onBootStarted();
-
-        /**
-         * Callback to indicate that Nfc starts to enable.
-         */
-        void onEnableStarted();
-
-        /**
-         * Callback to indicate that Nfc starts to disable.
-         */
-        void onDisableStarted();
-
-        /**
-         * Callback to indicate if NFC boots successfully or not.
-         * @param status the status code indicating if boot finished successfully
-         */
-        void onBootFinished(@StatusCode int status);
-
-        /**
-         * Callback to indicate if NFC is successfully enabled.
-         * @param status the status code indicating if enable finished successfully
-         */
-        void onEnableFinished(@StatusCode int status);
-
-        /**
-         * Callback to indicate if NFC is successfully disabled.
-         * @param status the status code indicating if disable finished successfully
-         */
-        void onDisableFinished(@StatusCode int status);
-
-        /**
-         * Check if NfcService tag dispatch need to be skipped.
-         * @param isSkipped The {@link Consumer} to be completed. If tag dispatch can be skipped,
-         *                  the {@link Consumer#accept(Object)} should be called with
-         *                  {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
-         */
-        void onTagDispatch(@NonNull Consumer<Boolean> isSkipped);
-
-        /**
-         * Notifies routing configuration is changed.
-         * @param isCommitRoutingSkipped The {@link Consumer} to be
-         * completed. If routing commit should be skipped,
-         * the {@link Consumer#accept(Object)} should be called with
-         * {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
-         */
-        void onRoutingChanged(@NonNull Consumer<Boolean> isCommitRoutingSkipped);
-
-        /**
-         * API to activate start stop cpu boost on hce event.
-         *
-         * <p>When HCE is activated, transferring data, and deactivated,
-         * must call this method to activate, start and stop cpu boost respectively.
-         * @param action Flag indicating actions to activate, start and stop cpu boost.
-         */
-        void onHceEventReceived(@HostCardEmulationAction int action);
-
-        /**
-         * API to notify when reader option has been changed using
-         * {@link NfcAdapter#enableReaderOption(boolean)} by some app.
-         * @param enabled Flag indicating ReaderMode enabled/disabled
-         */
-        void onReaderOptionChanged(boolean enabled);
-
-        /**
-        * Notifies NFC is activated in listen mode.
-        * NFC Forum NCI-2.3 ch.5.2.6 specification
-        *
-        * <p>NFCC is ready to communicate with a Card reader
-        *
-        * @param isActivated true, if card emulation activated, else de-activated.
-        */
-        void onCardEmulationActivated(boolean isActivated);
-
-        /**
-        * Notifies the Remote NFC Endpoint RF Field is detected.
-        * NFC Forum NCI-2.3 ch.5.3 specification
-        *
-        * @param isActive true, if RF Field is ON, else RF Field is OFF.
-        */
-        void onRfFieldDetected(boolean isActive);
-
-        /**
-        * Notifies the NFC RF discovery is started or in the IDLE state.
-        * NFC Forum NCI-2.3 ch.5.2 specification
-        *
-        * @param isDiscoveryStarted true, if RF discovery started, else RF state is Idle.
-        */
-        void onRfDiscoveryStarted(boolean isDiscoveryStarted);
-
-        /**
-        * Notifies the NFCEE (NFC Execution Environment) Listen has been activated.
-        *
-        * @param isActivated true, if EE Listen is ON, else EE Listen is OFF.
-        */
-        void onEeListenActivated(boolean isActivated);
-
-        /**
-        * Notifies that some NFCEE (NFC Execution Environment) has been updated.
-        *
-        * <p> This indicates that some applet has been installed/updated/removed in
-        * one of the NFCEE's.
-        * </p>
-        */
-        void onEeUpdated();
-
-        /**
-         * Gets the intent to find the OEM package in the OEM App market. If the consumer returns
-         * {@code null} or a timeout occurs, the intent from the first available package will be
-         * used instead.
-         *
-         * @param packages the OEM packages name stored in the tag
-         * @param intentConsumer The {@link Consumer} to be completed.
-         *                       The {@link Consumer#accept(Object)} should be called with
-         *                       the Intent required.
-         *
-         */
-        void onGetOemAppSearchIntent(@NonNull List<String> packages,
-                                     @NonNull Consumer<Intent> intentConsumer);
-
-        /**
-         * Checks if the NDEF message contains any specific OEM package executable content
-         *
-         * @param tag        the {@link android.nfc.Tag Tag}
-         * @param message NDEF Message to read from tag
-         * @param hasOemExecutableContent The {@link Consumer} to be completed. If there is
-         *                                OEM package executable content, the
-         *                                {@link Consumer#accept(Object)} should be called with
-         *                                {@link Boolean#TRUE}, otherwise call with
-         *                                {@link Boolean#FALSE}.
-         */
-        void onNdefMessage(@NonNull Tag tag, @NonNull NdefMessage message,
-                           @NonNull Consumer<Boolean> hasOemExecutableContent);
-
-        /**
-         * Callback to indicate the app chooser activity should be launched for handling CE
-         * transaction. This is invoked for example when there are more than 1 app installed that
-         * can handle the HCE transaction. OEMs can launch the Activity based
-         * on their requirement.
-         *
-         * @param selectedAid the selected AID from APDU
-         * @param services {@link ApduServiceInfo} of the service triggering the activity
-         * @param failedComponent the component failed to be resolved
-         * @param category the category of the service
-         */
-        void onLaunchHceAppChooserActivity(@NonNull String selectedAid,
-                                           @NonNull List<ApduServiceInfo> services,
-                                           @NonNull ComponentName failedComponent,
-                                           @NonNull String category);
-
-        /**
-         * Callback to indicate tap again dialog should be launched for handling HCE transaction.
-         * This is invoked for example when a CE service needs the device to unlocked before
-         * handling the transaction. OEMs can launch the Activity based on their requirement.
-         *
-         * @param service {@link ApduServiceInfo} of the service triggering the dialog
-         * @param category the category of the service
-         */
-        void onLaunchHceTapAgainDialog(@NonNull ApduServiceInfo service, @NonNull String category);
-
-        /**
-         * Callback to indicate that routing table is full and the OEM can optionally launch a
-         * dialog to request the user to remove some Card Emulation apps from the device to free
-         * routing table space.
-         */
-        void onRoutingTableFull();
-
-        /**
-         * Callback when OEM specified log event are notified.
-         * @param item the log items that contains log information of NFC event.
-         */
-        void onLogEventNotified(@NonNull OemLogItems item);
-
-        /**
-         * Callback to to extract OEM defined packages from given NDEF message when
-         * a NFC tag is detected. These are used to handle NFC tags encoded with a
-         * proprietary format for storing app name (Android native app format).
-         *
-         * @param message NDEF message containing OEM package names
-         * @param packageConsumer The {@link Consumer} to be completed.
-         *                        The {@link Consumer#accept(Object)} should be called with
-         *                        the list of package names.
-         */
-        void onExtractOemPackages(@NonNull NdefMessage message,
-                @NonNull Consumer<List<String>> packageConsumer);
-    }
-
-
-    /**
-     * Constructor to be used only by {@link NfcAdapter}.
-     */
-    NfcOemExtension(@NonNull Context context, @NonNull NfcAdapter adapter) {
-        mContext = context;
-        mAdapter = adapter;
-        mOemNfcExtensionCallback = new NfcOemExtensionCallback();
-    }
-
-    /**
-     * Get an instance of {@link T4tNdefNfcee} object for performing T4T (Type-4 Tag)
-     * NDEF (NFC Data Exchange Format) NFCEE (NFC Execution Environment) operations.
-     * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
-     * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
-     * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
-     *
-     * This is a singleton object which shall be used by OEM extension module to do NDEF-NFCEE
-     * read/write operations.
-     *
-     * <p>Returns {@link T4tNdefNfcee}
-     * <p>Does not cause any RF activity and does not block.
-     * @return NFC Data Exchange Format (NDEF) NFC Execution Environment (NFCEE) object
-     * @hide
-     */
-    @SystemApi
-    @NonNull
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public T4tNdefNfcee getT4tNdefNfcee() {
-        return T4tNdefNfcee.getInstance();
-    }
-
-    /**
-     * Register an {@link Callback} to listen for NFC oem extension callbacks
-     * Multiple clients can register and callbacks will be invoked asynchronously.
-     *
-     * <p>The provided callback will be invoked by the given {@link Executor}.
-     * As part of {@link #registerCallback(Executor, Callback)} the
-     * {@link Callback} will be invoked with current NFC state
-     * before the {@link #registerCallback(Executor, Callback)} function completes.
-     *
-     * @param executor an {@link Executor} to execute given callback
-     * @param callback oem implementation of {@link Callback}
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void registerCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull Callback callback) {
-        synchronized (mLock) {
-            if (executor == null || callback == null) {
-                Log.e(TAG, "Executor and Callback must not be null!");
-                throw new IllegalArgumentException();
-            }
-
-            if (mCallbackMap.containsKey(callback)) {
-                Log.e(TAG, "Callback already registered. Unregister existing callback before"
-                        + "registering");
-                throw new IllegalArgumentException();
-            }
-            mCallbackMap.put(callback, executor);
-            if (!mIsRegistered) {
-                NfcAdapter.callService(() -> {
-                    NfcAdapter.sService.registerOemExtensionCallback(mOemNfcExtensionCallback);
-                    mIsRegistered = true;
-                });
-            } else {
-                updateNfCState(callback, executor);
-            }
-        }
-    }
-
-    private void updateNfCState(Callback callback, Executor executor) {
-        if (callback != null) {
-            Log.i(TAG, "updateNfCState");
-            executor.execute(() -> {
-                callback.onCardEmulationActivated(mCardEmulationActivated);
-                callback.onRfFieldDetected(mRfFieldActivated);
-                callback.onRfDiscoveryStarted(mRfDiscoveryStarted);
-                callback.onEeListenActivated(mEeListenActivated);
-            });
-        }
-    }
-
-    /**
-     * Unregister the specified {@link Callback}
-     *
-     * <p>The same {@link Callback} object used when calling
-     * {@link #registerCallback(Executor, Callback)} must be used.
-     *
-     * <p>Callbacks are automatically unregistered when an application process goes away
-     *
-     * @param callback oem implementation of {@link Callback}
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void unregisterCallback(@NonNull Callback callback) {
-        synchronized (mLock) {
-            if (!mCallbackMap.containsKey(callback) || !mIsRegistered) {
-                Log.e(TAG, "Callback not registered");
-                throw new IllegalArgumentException();
-            }
-            if (mCallbackMap.size() == 1) {
-                NfcAdapter.callService(() -> {
-                    NfcAdapter.sService.unregisterOemExtensionCallback(mOemNfcExtensionCallback);
-                    mIsRegistered = false;
-                    mCallbackMap.remove(callback);
-                });
-            } else {
-                mCallbackMap.remove(callback);
-            }
-        }
-    }
-
-    /**
-     * Clear NfcService preference, interface method to clear NFC preference values on OEM specific
-     * events. For ex: on soft reset, Nfc default values needs to be overridden by OEM defaults.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void clearPreference() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.clearPreference());
-    }
-
-    /**
-     * Get the screen state from system and set it to current screen state.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void synchronizeScreenState() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.setScreenState());
-    }
-
-    /**
-     * Check if the firmware needs updating.
-     *
-     * <p>If an update is needed, a firmware will be triggered when NFC is disabled.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void maybeTriggerFirmwareUpdate() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.checkFirmware());
-    }
-
-    /**
-     * Get the Active NFCEE (NFC Execution Environment) List
-     *
-     * @return Map< String, @NfceeTechnology Integer >
-     *         A HashMap where keys are activated secure elements and
-     *         the values are bitmap of technologies supported by each secure element:
-     *          NFCEE_TECH_A == 0x1
-     *          NFCEE_TECH_B == 0x2
-     *          NFCEE_TECH_F == 0x4
-     *         and keys can contain "eSE" and "SIM" with a number,
-     *         in case of failure an empty map is returned.
-     *         @see Reader#getName() for the list of possible NFCEE names.
-     */
-    @NonNull
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public Map<String, Integer> getActiveNfceeList() {
-        return NfcAdapter.callServiceReturn(() ->
-            NfcAdapter.sService.fetchActiveNfceeList(), new HashMap<String, Integer>());
-    }
-
-    /**
-     * Sets NFC controller always on feature.
-     * <p>This API is for the NFCC internal state management. It allows to discriminate
-     * the controller function from the NFC function by keeping the NFC controller on without
-     * any NFC RF enabled if necessary.
-     * <p>This call is asynchronous, register listener {@link NfcAdapter.ControllerAlwaysOnListener}
-     * by {@link NfcAdapter#registerControllerAlwaysOnListener} to find out when the operation is
-     * complete.
-     * <p> Note: This adds more always on modes on top of existing
-     * {@link NfcAdapter#setControllerAlwaysOn(boolean)} API which can be used to set the NFCC in
-     * only {@link #ENABLE_DEFAULT} and {@link #DISABLE} modes.
-     * @param mode one of {@link ControllerMode} modes
-     * @throws UnsupportedOperationException if
-     *   <li> if FEATURE_NFC, FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     *   FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
-     *   are unavailable </li>
-     *   <li> if the feature is unavailable @see NfcAdapter#isNfcControllerAlwaysOnSupported() </li>
-     * @hide
-     * @see NfcAdapter#setControllerAlwaysOn(boolean)
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
-    public void setControllerAlwaysOnMode(@ControllerMode int mode) {
-        if (!NfcAdapter.sHasNfcFeature && !NfcAdapter.sHasCeFeature) {
-            throw new UnsupportedOperationException();
-        }
-        NfcAdapter.callService(() -> NfcAdapter.sService.setControllerAlwaysOn(mode));
-    }
-
-    /**
-     * Triggers NFC initialization. If OEM extension is registered
-     * (indicated via `enable_oem_extension` NFC overlay), the NFC stack initialization at bootup
-     * is delayed until the OEM extension app triggers the initialization via this call.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void triggerInitialization() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.triggerInitialization());
-    }
-
-    /**
-     * Gets the last user toggle status.
-     * @return true if NFC is set to ON, false otherwise
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean hasUserEnabledNfc() {
-        return NfcAdapter.callServiceReturn(() -> NfcAdapter.sService.getSettingStatus(), false);
-    }
-
-    /**
-     * Checks if the tag is present or not.
-     * @return true if the tag is present, false otherwise
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean isTagPresent() {
-        return NfcAdapter.callServiceReturn(() -> NfcAdapter.sService.isTagPresent(), false);
-    }
-
-    /**
-     * Pauses NFC tag reader mode polling for a {@code timeoutInMs} millisecond.
-     * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely.
-     * Use {@link #resumePolling()} to resume the polling.
-     * Use {@link #getMaxPausePollingTimeoutMs()} to check the max timeout value.
-     * @param timeoutInMs the pause polling duration in millisecond.
-     * @return status of the operation
-     * @throws IllegalArgumentException if timeoutInMs value is invalid
-     *         (0 < timeoutInMs < max).
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public @PollingStateChangeStatusCode int pausePolling(@DurationMillisLong long timeoutInMs) {
-        return NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sService.pausePolling(timeoutInMs),
-                POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
-    }
-
-    /**
-     * Resumes default NFC tag reader mode polling for the current device state if polling is
-     * paused. Calling this while already in polling is a no-op.
-     * @return status of the operation
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public @PollingStateChangeStatusCode int resumePolling() {
-        return NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sService.resumePolling(),
-                POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
-    }
-
-    /**
-     * Gets the max pause polling timeout value in millisecond.
-     * @return long integer representing the max timeout
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @DurationMillisLong
-    public long getMaxPausePollingTimeoutMills() {
-        return NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sService.getMaxPausePollingTimeoutMs(), 0L);
-    }
-
-    /**
-     * Set whether to enable auto routing change or not (enabled by default).
-     * If disabled, routing targets are limited to a single off-host destination.
-     *
-     * @param state status of auto routing change, true if enable, otherwise false
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void setAutoChangeEnabled(boolean state) {
-        NfcAdapter.callService(() ->
-                NfcAdapter.sCardEmulationService.setAutoChangeStatus(state));
-    }
-
-    /**
-     * Check if auto routing change is enabled or not.
-     *
-     * @return true if enabled, otherwise false
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean isAutoChangeEnabled() {
-        return NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sCardEmulationService.isAutoChangeEnabled(), false);
-    }
-
-    /**
-     * Get current routing status
-     *
-     * @return {@link RoutingStatus} indicating the default route, default ISO-DEP
-     * route and default off-host route.
-     */
-    @NonNull
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    public RoutingStatus getRoutingStatus() {
-        List<String> status = NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sCardEmulationService.getRoutingStatus(), new ArrayList<>());
-        return new RoutingStatus(routeStringToInt(status.get(0)),
-                routeStringToInt(status.get(1)),
-                routeStringToInt(status.get(2)));
-    }
-
-    /**
-     * Overwrites NFC controller routing table, which includes Protocol Route, Technology Route,
-     * and Empty AID Route.
-     *
-     * The parameter set to
-     * {@link ProtocolAndTechnologyRoute#PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET}
-     * can be used to keep current values for that entry. At least one route should be overridden
-     * when calling this API, otherwise throw {@link IllegalArgumentException}.
-     *
-     * @param protocol ISO-DEP route destination, where the possible inputs are defined in
-     *                 {@link ProtocolAndTechnologyRoute}.
-     * @param technology Tech-A, Tech-B and Tech-F route destination, where the possible inputs
-     *                   are defined in
-     *                   {@link ProtocolAndTechnologyRoute}
-     * @param emptyAid Zero-length AID route destination, where the possible inputs are defined in
-     *                 {@link ProtocolAndTechnologyRoute}
-     * @param systemCode System Code route destination, where the possible inputs are defined in
-     *                   {@link ProtocolAndTechnologyRoute}
-     */
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public void overwriteRoutingTable(
-            @CardEmulation.ProtocolAndTechnologyRoute int protocol,
-            @CardEmulation.ProtocolAndTechnologyRoute int technology,
-            @CardEmulation.ProtocolAndTechnologyRoute int emptyAid,
-            @CardEmulation.ProtocolAndTechnologyRoute int systemCode) {
-
-        String protocolRoute = routeIntToString(protocol);
-        String technologyRoute = routeIntToString(technology);
-        String emptyAidRoute = routeIntToString(emptyAid);
-        String systemCodeRoute = routeIntToString(systemCode);
-
-        NfcAdapter.callService(() ->
-                NfcAdapter.sCardEmulationService.overwriteRoutingTable(
-                        mContext.getUser().getIdentifier(),
-                        emptyAidRoute,
-                        protocolRoute,
-                        technologyRoute,
-                        systemCodeRoute
-                ));
-    }
-
-    /**
-     * Gets current routing table entries.
-     * @return List of {@link NfcRoutingTableEntry} representing current routing table
-     */
-    @NonNull
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public List<NfcRoutingTableEntry> getRoutingTable() {
-        List<Entry> entryList = NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sService.getRoutingTableEntryList(), null);
-        List<NfcRoutingTableEntry> result = new ArrayList<>();
-        for (Entry entry : entryList) {
-            switch (entry.getType()) {
-                case TYPE_TECHNOLOGY -> result.add(
-                        new RoutingTableTechnologyEntry(entry.getNfceeId(),
-                                RoutingTableTechnologyEntry.techStringToInt(entry.getEntry()),
-                                routeStringToInt(entry.getRoutingType()))
-                );
-                case TYPE_PROTOCOL -> result.add(
-                        new RoutingTableProtocolEntry(entry.getNfceeId(),
-                                RoutingTableProtocolEntry.protocolStringToInt(entry.getEntry()),
-                                routeStringToInt(entry.getRoutingType()))
-                );
-                case TYPE_AID -> result.add(
-                        new RoutingTableAidEntry(entry.getNfceeId(), entry.getEntry(),
-                                routeStringToInt(entry.getRoutingType()))
-                );
-                case TYPE_SYSTEMCODE -> result.add(
-                        new RoutingTableSystemCodeEntry(entry.getNfceeId(),
-                                entry.getEntry().getBytes(StandardCharsets.UTF_8),
-                                routeStringToInt(entry.getRoutingType()))
-                );
-            }
-        }
-        return result;
-    }
-
-    /**
-     * API to force a routing table commit.
-     * @return a {@link StatusCode} to indicate if commit routing succeeded or not
-     */
-    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @CommitRoutingStatusCode
-    public int forceRoutingTableCommit() {
-        return NfcAdapter.callServiceReturn(
-                () -> NfcAdapter.sService.commitRouting(), COMMIT_ROUTING_STATUS_FAILED);
-    }
-
-    private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub {
-
-        @Override
-        public void onTagConnected(boolean connected) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(connected, cb::onTagConnected, ex));
-        }
-
-        @Override
-        public void onCardEmulationActivated(boolean isActivated) throws RemoteException {
-            mCardEmulationActivated = isActivated;
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(isActivated, cb::onCardEmulationActivated, ex));
-        }
-
-        @Override
-        public void onRfFieldDetected(boolean isActive) throws RemoteException {
-            mRfFieldActivated = isActive;
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(isActive, cb::onRfFieldDetected, ex));
-        }
-
-        @Override
-        public void onRfDiscoveryStarted(boolean isDiscoveryStarted) throws RemoteException {
-            mRfDiscoveryStarted = isDiscoveryStarted;
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(isDiscoveryStarted, cb::onRfDiscoveryStarted, ex));
-        }
-
-        @Override
-        public void onEeListenActivated(boolean isActivated) throws RemoteException {
-            mEeListenActivated = isActivated;
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(isActivated, cb::onEeListenActivated, ex));
-        }
-
-        @Override
-        public void onEeUpdated() throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(null, (Object input) -> cb.onEeUpdated(), ex));
-        }
-
-        @Override
-        public void onStateUpdated(int state) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(state, cb::onStateUpdated, ex));
-        }
-
-        @Override
-        public void onApplyRouting(ResultReceiver isSkipped) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(
-                        new ReceiverWrapper<>(isSkipped), cb::onApplyRouting, ex));
-        }
-        @Override
-        public void onNdefRead(ResultReceiver isSkipped) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(
-                        new ReceiverWrapper<>(isSkipped), cb::onNdefRead, ex));
-        }
-        @Override
-        public void onEnable(ResultReceiver isAllowed) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(
-                        new ReceiverWrapper<>(isAllowed), cb::onEnableRequested, ex));
-        }
-        @Override
-        public void onDisable(ResultReceiver isAllowed) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(
-                        new ReceiverWrapper<>(isAllowed), cb::onDisableRequested, ex));
-        }
-        @Override
-        public void onBootStarted() throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(null, (Object input) -> cb.onBootStarted(), ex));
-        }
-        @Override
-        public void onEnableStarted() throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(null, (Object input) -> cb.onEnableStarted(), ex));
-        }
-        @Override
-        public void onDisableStarted() throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(null, (Object input) -> cb.onDisableStarted(), ex));
-        }
-        @Override
-        public void onBootFinished(int status) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(status, cb::onBootFinished, ex));
-        }
-        @Override
-        public void onEnableFinished(int status) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(status, cb::onEnableFinished, ex));
-        }
-        @Override
-        public void onDisableFinished(int status) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(status, cb::onDisableFinished, ex));
-        }
-        @Override
-        public void onTagDispatch(ResultReceiver isSkipped) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(
-                        new ReceiverWrapper<>(isSkipped), cb::onTagDispatch, ex));
-        }
-        @Override
-        public void onRoutingChanged(ResultReceiver isSkipped) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(
-                            new ReceiverWrapper<>(isSkipped), cb::onRoutingChanged, ex));
-        }
-        @Override
-        public void onHceEventReceived(int action) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(action, cb::onHceEventReceived, ex));
-        }
-
-        @Override
-        public void onReaderOptionChanged(boolean enabled) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(enabled, cb::onReaderOptionChanged, ex));
-        }
-
-        public void onRoutingTableFull() throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(null,
-                            (Object input) -> cb.onRoutingTableFull(), ex));
-        }
-
-        @Override
-        public void onGetOemAppSearchIntent(List<String> packages, ResultReceiver intentConsumer)
-                throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoid2ArgCallback(packages, new ReceiverWrapper<>(intentConsumer),
-                            cb::onGetOemAppSearchIntent, ex));
-        }
-
-        @Override
-        public void onNdefMessage(Tag tag, NdefMessage message,
-                                  ResultReceiver hasOemExecutableContent) throws RemoteException {
-            mCallbackMap.forEach((cb, ex) -> {
-                synchronized (mLock) {
-                    final long identity = Binder.clearCallingIdentity();
-                    try {
-                        ex.execute(() -> cb.onNdefMessage(
-                                tag, message, new ReceiverWrapper<>(hasOemExecutableContent)));
-                    } catch (RuntimeException exception) {
-                        throw exception;
-                    } finally {
-                        Binder.restoreCallingIdentity(identity);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onLaunchHceAppChooserActivity(String selectedAid,
-                                                  List<ApduServiceInfo> services,
-                                                  ComponentName failedComponent, String category)
-                throws RemoteException {
-            mCallbackMap.forEach((cb, ex) -> {
-                synchronized (mLock) {
-                    final long identity = Binder.clearCallingIdentity();
-                    try {
-                        ex.execute(() -> cb.onLaunchHceAppChooserActivity(
-                                selectedAid, services, failedComponent, category));
-                    } catch (RuntimeException exception) {
-                        throw exception;
-                    } finally {
-                        Binder.restoreCallingIdentity(identity);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onLaunchHceTapAgainActivity(ApduServiceInfo service, String category)
-                throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoid2ArgCallback(service, category, cb::onLaunchHceTapAgainDialog, ex));
-        }
-
-        @Override
-        public void onLogEventNotified(OemLogItems item) throws RemoteException  {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoidCallback(item, cb::onLogEventNotified, ex));
-        }
-
-        @Override
-        public void onExtractOemPackages(NdefMessage message, ResultReceiver packageConsumer)
-                throws RemoteException {
-            mCallbackMap.forEach((cb, ex) ->
-                    handleVoid2ArgCallback(message,
-                            new ReceiverWrapper<>(packageConsumer),
-                            cb::onExtractOemPackages, ex));
-        }
-
-        private <T> void handleVoidCallback(
-                T input, Consumer<T> callbackMethod, Executor executor) {
-            synchronized (mLock) {
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    executor.execute(() -> callbackMethod.accept(input));
-                } catch (RuntimeException ex) {
-                    throw ex;
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-        }
-
-        private <T1, T2> void handleVoid2ArgCallback(
-                T1 input1, T2 input2, BiConsumer<T1, T2> callbackMethod, Executor executor) {
-            synchronized (mLock) {
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    executor.execute(() -> callbackMethod.accept(input1, input2));
-                } catch (RuntimeException ex) {
-                    throw ex;
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-        }
-
-        private <S, T> S handleNonVoidCallbackWithInput(
-                S defaultValue, T input, Function<T, S> callbackMethod) throws RemoteException {
-            synchronized (mLock) {
-                final long identity = Binder.clearCallingIdentity();
-                S result = defaultValue;
-                try {
-                    ExecutorService executor = Executors.newSingleThreadExecutor();
-                    FutureTask<S> futureTask = new FutureTask<>(() -> callbackMethod.apply(input));
-                    var unused = executor.submit(futureTask);
-                    try {
-                        result = futureTask.get(
-                                OEM_EXTENSION_RESPONSE_THRESHOLD_MS, TimeUnit.MILLISECONDS);
-                    } catch (ExecutionException | InterruptedException e) {
-                        e.printStackTrace();
-                    } catch (TimeoutException e) {
-                        Log.w(TAG, "Callback timed out: " + callbackMethod);
-                        e.printStackTrace();
-                    } finally {
-                        executor.shutdown();
-                    }
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-                return result;
-            }
-        }
-
-        private <T> T handleNonVoidCallbackWithoutInput(T defaultValue, Supplier<T> callbackMethod)
-                throws RemoteException {
-            synchronized (mLock) {
-                final long identity = Binder.clearCallingIdentity();
-                T result = defaultValue;
-                try {
-                    ExecutorService executor = Executors.newSingleThreadExecutor();
-                    FutureTask<T> futureTask = new FutureTask<>(callbackMethod::get);
-                    var unused = executor.submit(futureTask);
-                    try {
-                        result = futureTask.get(
-                                OEM_EXTENSION_RESPONSE_THRESHOLD_MS, TimeUnit.MILLISECONDS);
-                    } catch (ExecutionException | InterruptedException e) {
-                        e.printStackTrace();
-                    } catch (TimeoutException e) {
-                        Log.w(TAG, "Callback timed out: " + callbackMethod);
-                        e.printStackTrace();
-                    } finally {
-                        executor.shutdown();
-                    }
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-                return result;
-            }
-        }
-    }
-
-    private @CardEmulation.ProtocolAndTechnologyRoute int routeStringToInt(String route) {
-        if (route.equals("DH")) {
-            return PROTOCOL_AND_TECHNOLOGY_ROUTE_DH;
-        } else if (route.startsWith("eSE")) {
-            return PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE;
-        } else if (route.startsWith("SIM")) {
-            return PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC;
-        } else {
-            throw new IllegalStateException("Unexpected value: " + route);
-        }
-    }
-
-    private class ReceiverWrapper<T> implements Consumer<T> {
-        private final ResultReceiver mResultReceiver;
-
-        ReceiverWrapper(ResultReceiver resultReceiver) {
-            mResultReceiver = resultReceiver;
-        }
-
-        @Override
-        public void accept(T result) {
-            if (result instanceof Boolean) {
-                mResultReceiver.send((Boolean) result ? 1 : 0, null);
-            } else if (result instanceof Intent) {
-                Bundle bundle = new Bundle();
-                bundle.putParcelable("intent", (Intent) result);
-                mResultReceiver.send(0, bundle);
-            } else if (result instanceof List<?> list) {
-                if (list.stream().allMatch(String.class::isInstance)) {
-                    Bundle bundle = new Bundle();
-                    bundle.putStringArray("packageNames",
-                            list.stream().map(pkg -> (String) pkg).toArray(String[]::new));
-                    mResultReceiver.send(0, bundle);
-                }
-            }
-        }
-
-        @Override
-        public Consumer<T> andThen(Consumer<? super T> after) {
-            return Consumer.super.andThen(after);
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/NfcRoutingTableEntry.java b/nfc/java/android/nfc/NfcRoutingTableEntry.java
deleted file mode 100644
index 4153779..0000000
--- a/nfc/java/android/nfc/NfcRoutingTableEntry.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Class to represent an entry of routing table. This class is abstract and extended by
- * {@link RoutingTableTechnologyEntry}, {@link RoutingTableProtocolEntry},
- * {@link RoutingTableAidEntry} and {@link RoutingTableSystemCodeEntry}.
- *
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public abstract class NfcRoutingTableEntry {
-    private final int mNfceeId;
-    private final int mType;
-    private final int mRouteType;
-
-    /**
-     * AID routing table type.
-     */
-    public static final int TYPE_AID = 0;
-    /**
-     * Protocol routing table type.
-     */
-    public static final int TYPE_PROTOCOL = 1;
-    /**
-     * Technology routing table type.
-     */
-    public static final int TYPE_TECHNOLOGY = 2;
-    /**
-     * System Code routing table type.
-     */
-    public static final int TYPE_SYSTEM_CODE = 3;
-
-    /**
-     * Possible type of this routing table entry.
-     * @hide
-     */
-    @IntDef(prefix = "TYPE_", value = {
-            TYPE_AID,
-            TYPE_PROTOCOL,
-            TYPE_TECHNOLOGY,
-            TYPE_SYSTEM_CODE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface RoutingTableType {}
-
-    /** @hide */
-    protected NfcRoutingTableEntry(int nfceeId, @RoutingTableType int type,
-            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
-        mNfceeId = nfceeId;
-        mType = type;
-        mRouteType = routeType;
-    }
-
-    /**
-     * Gets the NFCEE Id of this entry.
-     * @return an integer of NFCEE Id.
-     */
-    public int getNfceeId() {
-        return mNfceeId;
-    }
-
-    /**
-     * Get the type of this entry.
-     * @return an integer defined in {@link RoutingTableType}
-     */
-    @RoutingTableType
-    public int getType() {
-        return mType;
-    }
-
-    /**
-     * Get the route type of this entry.
-     * @return an integer defined in
-     * {@link android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute}
-     */
-    @CardEmulation.ProtocolAndTechnologyRoute
-    public int getRouteType() {
-        return mRouteType;
-    }
-}
diff --git a/nfc/java/android/nfc/NfcVendorNciCallbackListener.java b/nfc/java/android/nfc/NfcVendorNciCallbackListener.java
deleted file mode 100644
index 742d75f..0000000
--- a/nfc/java/android/nfc/NfcVendorNciCallbackListener.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import android.annotation.NonNull;
-import android.nfc.NfcAdapter.NfcVendorNciCallback;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * @hide
- */
-public final class NfcVendorNciCallbackListener extends INfcVendorNciCallback.Stub {
-    private static final String TAG = "Nfc.NfcVendorNciCallbacks";
-    private final INfcAdapter mAdapter;
-    private boolean mIsRegistered = false;
-    private final Map<NfcVendorNciCallback, Executor> mCallbackMap = new HashMap<>();
-
-    public NfcVendorNciCallbackListener(@NonNull INfcAdapter adapter) {
-        mAdapter = adapter;
-    }
-
-    public void register(@NonNull Executor executor, @NonNull NfcVendorNciCallback callback) {
-        synchronized (this) {
-            if (mCallbackMap.containsKey(callback)) {
-                return;
-            }
-            mCallbackMap.put(callback, executor);
-            if (!mIsRegistered) {
-                try {
-                    mAdapter.registerVendorExtensionCallback(this);
-                    mIsRegistered = true;
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to register adapter state callback");
-                    mCallbackMap.remove(callback);
-                    throw e.rethrowFromSystemServer();
-                }
-            }
-        }
-    }
-
-    public void unregister(@NonNull NfcVendorNciCallback callback) {
-        synchronized (this) {
-            if (!mCallbackMap.containsKey(callback) || !mIsRegistered) {
-                return;
-            }
-            if (mCallbackMap.size() == 1) {
-                try {
-                    mAdapter.unregisterVendorExtensionCallback(this);
-                    mIsRegistered = false;
-                    mCallbackMap.remove(callback);
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to unregister AdapterStateCallback with service");
-                    throw e.rethrowFromSystemServer();
-                }
-            } else {
-                mCallbackMap.remove(callback);
-            }
-        }
-    }
-
-    @Override
-    public void onVendorResponseReceived(int gid, int oid, @NonNull byte[] payload)
-            throws RemoteException {
-        synchronized (this) {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                for (NfcVendorNciCallback callback : mCallbackMap.keySet()) {
-                    Executor executor = mCallbackMap.get(callback);
-                    executor.execute(() -> callback.onVendorNciResponse(gid, oid, payload));
-                }
-            } catch (RuntimeException ex) {
-                throw ex;
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    @Override
-    public void onVendorNotificationReceived(int gid, int oid, @NonNull byte[] payload)
-            throws RemoteException {
-        synchronized (this) {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                for (NfcVendorNciCallback callback : mCallbackMap.keySet()) {
-                    Executor executor = mCallbackMap.get(callback);
-                    executor.execute(() -> callback.onVendorNciNotification(gid, oid, payload));
-                }
-            } catch (RuntimeException ex) {
-                throw ex;
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/NfcWlcStateListener.java b/nfc/java/android/nfc/NfcWlcStateListener.java
deleted file mode 100644
index 890cb09..0000000
--- a/nfc/java/android/nfc/NfcWlcStateListener.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 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 android.nfc;
-
-import android.annotation.NonNull;
-import android.nfc.NfcAdapter.WlcStateListener;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * @hide
- */
-public class NfcWlcStateListener extends INfcWlcStateListener.Stub {
-    private static final String TAG = NfcWlcStateListener.class.getSimpleName();
-
-    private final INfcAdapter mAdapter;
-
-    private final Map<WlcStateListener, Executor> mListenerMap = new HashMap<>();
-
-    private WlcListenerDeviceInfo mCurrentState = null;
-    private boolean mIsRegistered = false;
-
-    public NfcWlcStateListener(@NonNull INfcAdapter adapter) {
-        mAdapter = adapter;
-    }
-
-    /**
-     * Register a {@link WlcStateListener} with this
-     * {@link WlcStateListener}
-     *
-     * @param executor an {@link Executor} to execute given listener
-     * @param listener user implementation of the {@link WlcStateListener}
-     */
-    public void register(@NonNull Executor executor, @NonNull WlcStateListener listener) {
-        synchronized (this) {
-            if (mListenerMap.containsKey(listener)) {
-                return;
-            }
-
-            mListenerMap.put(listener, executor);
-
-            if (!mIsRegistered) {
-                try {
-                    mAdapter.registerWlcStateListener(this);
-                    mIsRegistered = true;
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to register");
-                }
-            }
-        }
-    }
-
-    /**
-     * Unregister the specified {@link WlcStateListener}
-     *
-     * @param listener user implementation of the {@link WlcStateListener}
-     */
-    public void unregister(@NonNull WlcStateListener listener) {
-        synchronized (this) {
-            if (!mListenerMap.containsKey(listener)) {
-                return;
-            }
-
-            mListenerMap.remove(listener);
-
-            if (mListenerMap.isEmpty() && mIsRegistered) {
-                try {
-                    mAdapter.unregisterWlcStateListener(this);
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Failed to unregister");
-                }
-                mIsRegistered = false;
-            }
-        }
-    }
-
-    private void sendCurrentState(@NonNull WlcStateListener listener) {
-        synchronized (this) {
-            Executor executor = mListenerMap.get(listener);
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                if (Flags.enableNfcCharging()) {
-                    executor.execute(() -> listener.onWlcStateChanged(
-                            mCurrentState));
-                }
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    @Override
-    public void onWlcStateChanged(@NonNull WlcListenerDeviceInfo wlcListenerDeviceInfo) {
-        synchronized (this) {
-            mCurrentState = wlcListenerDeviceInfo;
-
-            for (WlcStateListener cb : mListenerMap.keySet()) {
-                sendCurrentState(cb);
-            }
-        }
-    }
-}
-
diff --git a/nfc/java/android/nfc/OemLogItems.java b/nfc/java/android/nfc/OemLogItems.java
deleted file mode 100644
index 4f3e199..0000000
--- a/nfc/java/android/nfc/OemLogItems.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*

- * Copyright 2024 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 android.nfc;

-

-import android.annotation.FlaggedApi;

-import android.annotation.IntDef;

-import android.annotation.NonNull;

-import android.annotation.Nullable;

-import android.annotation.SystemApi;

-import android.os.Parcel;

-import android.os.Parcelable;

-

-import java.lang.annotation.Retention;

-import java.lang.annotation.RetentionPolicy;

-import java.time.Instant;

-

-/**

- * A log class for OEMs to get log information of NFC events.

- * @hide

- */

-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)

-@SystemApi

-public final class OemLogItems implements Parcelable {

-    /**

-     * Used when RF field state is changed.

-     */

-    public static final int LOG_ACTION_RF_FIELD_STATE_CHANGED = 0X01;

-    /**

-     * Used when NFC is toggled. Event should be set to {@link LogEvent#EVENT_ENABLE} or

-     * {@link LogEvent#EVENT_DISABLE} if this action is used.

-     */

-    public static final int LOG_ACTION_NFC_TOGGLE = 0x0201;

-    /**

-     * Used when sending host routing status.

-     */

-    public static final int LOG_ACTION_HCE_DATA = 0x0204;

-    /**

-     * Used when screen state is changed.

-     */

-    public static final int LOG_ACTION_SCREEN_STATE_CHANGED = 0x0206;

-    /**

-     * Used when tag is detected.

-     */

-    public static final int LOG_ACTION_TAG_DETECTED = 0x03;

-

-    /**

-     * @hide

-     */

-    @IntDef(prefix = { "LOG_ACTION_" }, value = {

-            LOG_ACTION_RF_FIELD_STATE_CHANGED,

-            LOG_ACTION_NFC_TOGGLE,

-            LOG_ACTION_HCE_DATA,

-            LOG_ACTION_SCREEN_STATE_CHANGED,

-            LOG_ACTION_TAG_DETECTED,

-    })

-    @Retention(RetentionPolicy.SOURCE)

-    public @interface LogAction {}

-

-    /**

-     * Represents the event is not set.

-     */

-    public static final int EVENT_UNSET = 0;

-    /**

-     * Represents nfc enable is called.

-     */

-    public static final int EVENT_ENABLE = 1;

-    /**

-     * Represents nfc disable is called.

-     */

-    public static final int EVENT_DISABLE = 2;

-    /** @hide */

-    @IntDef(prefix = { "EVENT_" }, value = {

-            EVENT_UNSET,

-            EVENT_ENABLE,

-            EVENT_DISABLE,

-    })

-    @Retention(RetentionPolicy.SOURCE)

-    public @interface LogEvent {}

-    private int mAction;

-    private int mEvent;

-    private int mCallingPid;

-    private byte[] mCommandApdus;

-    private byte[] mResponseApdus;

-    private Instant mRfFieldOnTime;

-    private Tag mTag;

-

-    /** @hide */

-    public OemLogItems(@LogAction int action, @LogEvent int event, int callingPid,

-            byte[] commandApdus, byte[] responseApdus, Instant rfFieldOnTime,

-            Tag tag) {

-        mAction = action;

-        mEvent = event;

-        mTag = tag;

-        mCallingPid = callingPid;

-        mCommandApdus = commandApdus;

-        mResponseApdus = responseApdus;

-        mRfFieldOnTime = rfFieldOnTime;

-    }

-

-    /**

-     * Describe the kinds of special objects contained in this Parcelable

-     * instance's marshaled representation. For example, if the object will

-     * include a file descriptor in the output of {@link #writeToParcel(Parcel, int)},

-     * the return value of this method must include the

-     * {@link #CONTENTS_FILE_DESCRIPTOR} bit.

-     *

-     * @return a bitmask indicating the set of special object types marshaled

-     * by this Parcelable object instance.

-     */

-    @Override

-    public int describeContents() {

-        return 0;

-    }

-

-    /**

-     * Flatten this object in to a Parcel.

-     *

-     * @param dest  The Parcel in which the object should be written.

-     * @param flags Additional flags about how the object should be written.

-     *              May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.

-     */

-    @Override

-    public void writeToParcel(@NonNull Parcel dest, int flags) {

-        dest.writeInt(mAction);

-        dest.writeInt(mEvent);

-        dest.writeInt(mCallingPid);

-        dest.writeInt(mCommandApdus.length);

-        dest.writeByteArray(mCommandApdus);

-        dest.writeInt(mResponseApdus.length);

-        dest.writeByteArray(mResponseApdus);

-        dest.writeBoolean(mRfFieldOnTime != null);

-        if (mRfFieldOnTime != null) {

-            dest.writeLong(mRfFieldOnTime.getEpochSecond());

-            dest.writeInt(mRfFieldOnTime.getNano());

-        }

-        dest.writeParcelable(mTag, 0);

-    }

-

-    /** @hide */

-    public static class Builder {

-        private final OemLogItems mItem;

-

-        public Builder(@LogAction int type) {

-            mItem = new OemLogItems(type, EVENT_UNSET, 0, new byte[0], new byte[0], null, null);

-        }

-

-        /** Setter of the log action. */

-        public OemLogItems.Builder setAction(@LogAction int action) {

-            mItem.mAction = action;

-            return this;

-        }

-

-        /** Setter of the log calling event. */

-        public OemLogItems.Builder setCallingEvent(@LogEvent int event) {

-            mItem.mEvent = event;

-            return this;

-        }

-

-        /** Setter of the log calling Pid. */

-        public OemLogItems.Builder setCallingPid(int pid) {

-            mItem.mCallingPid = pid;

-            return this;

-        }

-

-        /** Setter of APDU command. */

-        public OemLogItems.Builder setApduCommand(byte[] apdus) {

-            mItem.mCommandApdus = apdus;

-            return this;

-        }

-

-        /** Setter of RF field on time. */

-        public OemLogItems.Builder setRfFieldOnTime(Instant time) {

-            mItem.mRfFieldOnTime = time;

-            return this;

-        }

-

-        /** Setter of APDU response. */

-        public OemLogItems.Builder setApduResponse(byte[] apdus) {

-            mItem.mResponseApdus = apdus;

-            return this;

-        }

-

-        /** Setter of dispatched tag. */

-        public OemLogItems.Builder setTag(Tag tag) {

-            mItem.mTag = tag;

-            return this;

-        }

-

-        /** Builds an {@link OemLogItems} instance. */

-        public OemLogItems build() {

-            return mItem;

-        }

-    }

-

-    /**

-     * Gets the action of this log.

-     * @return one of {@link LogAction}

-     */

-    @LogAction

-    public int getAction() {

-        return mAction;

-    }

-

-    /**

-     * Gets the event of this log. This will be set to {@link LogEvent#EVENT_ENABLE} or

-     * {@link LogEvent#EVENT_DISABLE} only when action is set to

-     * {@link LogAction#LOG_ACTION_NFC_TOGGLE}

-     * @return one of {@link LogEvent}

-     */

-    @LogEvent

-    public int getEvent() {

-        return mEvent;

-    }

-

-    /**

-     * Gets the calling Pid of this log. This field will be set only when action is set to

-     * {@link LogAction#LOG_ACTION_NFC_TOGGLE}

-     * @return calling Pid

-     */

-    public int getCallingPid() {

-        return mCallingPid;

-    }

-

-    /**

-     * Gets the command APDUs of this log. This field will be set only when action is set to

-     * {@link LogAction#LOG_ACTION_HCE_DATA}

-     * @return a byte array of command APDUs with the same format as

-     * {@link android.nfc.cardemulation.HostApduService#sendResponseApdu(byte[])}

-     */

-    @Nullable

-    public byte[] getCommandApdu() {

-        return mCommandApdus;

-    }

-

-    /**

-     * Gets the response APDUs of this log. This field will be set only when action is set to

-     * {@link LogAction#LOG_ACTION_HCE_DATA}

-     * @return a byte array of response APDUs with the same format as

-     * {@link android.nfc.cardemulation.HostApduService#sendResponseApdu(byte[])}

-     */

-    @Nullable

-    public byte[] getResponseApdu() {

-        return mResponseApdus;

-    }

-

-    /**

-     * Gets the RF field event time in this log in millisecond. This field will be set only when

-     * action is set to {@link LogAction#LOG_ACTION_RF_FIELD_STATE_CHANGED}

-     * @return an {@link Instant} of RF field event time.

-     */

-    @Nullable

-    public Instant getRfFieldEventTimeMillis() {

-        return mRfFieldOnTime;

-    }

-

-    /**

-     * Gets the tag of this log. This field will be set only when action is set to

-     * {@link LogAction#LOG_ACTION_TAG_DETECTED}

-     * @return a detected {@link Tag} in {@link #LOG_ACTION_TAG_DETECTED} case. Return

-     * null otherwise.

-     */

-    @Nullable

-    public Tag getTag() {

-        return mTag;

-    }

-

-    private String byteToHex(byte[] bytes) {

-        char[] HexArray = "0123456789ABCDEF".toCharArray();

-        char[] hexChars = new char[bytes.length * 2];

-        for (int j = 0; j < bytes.length; j++) {

-            int v = bytes[j] & 0xFF;

-            hexChars[j * 2] = HexArray[v >>> 4];

-            hexChars[j * 2 + 1] = HexArray[v & 0x0F];

-        }

-        return new String(hexChars);

-    }

-

-    @Override

-    public String toString() {

-        return "[mCommandApdus: "

-                + ((mCommandApdus != null) ? byteToHex(mCommandApdus) : "null")

-                + "[mResponseApdus: "

-                + ((mResponseApdus != null) ? byteToHex(mResponseApdus) : "null")

-                + ", mCallingApi= " + mEvent

-                + ", mAction= " + mAction

-                + ", mCallingPId = " + mCallingPid

-                + ", mRfFieldOnTime= " + mRfFieldOnTime;

-    }

-    private OemLogItems(Parcel in) {

-        this.mAction = in.readInt();

-        this.mEvent = in.readInt();

-        this.mCallingPid = in.readInt();

-        this.mCommandApdus = new byte[in.readInt()];

-        in.readByteArray(this.mCommandApdus);

-        this.mResponseApdus = new byte[in.readInt()];

-        in.readByteArray(this.mResponseApdus);

-        boolean isRfFieldOnTimeSet = in.readBoolean();

-        if (isRfFieldOnTimeSet) {

-            this.mRfFieldOnTime = Instant.ofEpochSecond(in.readLong(), in.readInt());

-        } else {

-            this.mRfFieldOnTime = null;

-        }

-        this.mTag = in.readParcelable(Tag.class.getClassLoader(), Tag.class);

-    }

-

-    public static final @NonNull Parcelable.Creator<OemLogItems> CREATOR =

-            new Parcelable.Creator<OemLogItems>() {

-                @Override

-                public OemLogItems createFromParcel(Parcel in) {

-                    return new OemLogItems(in);

-                }

-

-                @Override

-                public OemLogItems[] newArray(int size) {

-                    return new OemLogItems[size];

-                }

-            };

-

-}

diff --git a/nfc/java/android/nfc/Placeholder.java b/nfc/java/android/nfc/Placeholder.java
deleted file mode 100644
index 3509644..0000000
--- a/nfc/java/android/nfc/Placeholder.java
+++ /dev/null
@@ -1,27 +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 android.nfc;
-
-/**
- * Placeholder class so new framework-nfc module isn't empty, will be removed once module is
- * populated.
- *
- * @hide
- *
- */
-public class Placeholder {
-}
diff --git a/nfc/java/android/nfc/RoutingStatus.java b/nfc/java/android/nfc/RoutingStatus.java
deleted file mode 100644
index 4a1b1f3..0000000
--- a/nfc/java/android/nfc/RoutingStatus.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-/**
- * A class indicating default route, ISO-DEP route and off-host route.
- *
- * @hide
- */
-@SystemApi
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-public class RoutingStatus {
-    private final @CardEmulation.ProtocolAndTechnologyRoute int mDefaultRoute;
-    private final @CardEmulation.ProtocolAndTechnologyRoute int mDefaultIsoDepRoute;
-    private final @CardEmulation.ProtocolAndTechnologyRoute int mDefaultOffHostRoute;
-
-    RoutingStatus(@CardEmulation.ProtocolAndTechnologyRoute int mDefaultRoute,
-                  @CardEmulation.ProtocolAndTechnologyRoute int mDefaultIsoDepRoute,
-                  @CardEmulation.ProtocolAndTechnologyRoute int mDefaultOffHostRoute) {
-        this.mDefaultRoute = mDefaultRoute;
-        this.mDefaultIsoDepRoute = mDefaultIsoDepRoute;
-        this.mDefaultOffHostRoute = mDefaultOffHostRoute;
-    }
-
-    /**
-     * Getter of the default route.
-     * @return an integer defined in
-     * {@link android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute}
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @CardEmulation.ProtocolAndTechnologyRoute
-    public int getDefaultRoute() {
-        return mDefaultRoute;
-    }
-
-    /**
-     * Getter of the default ISO-DEP route.
-     * @return an integer defined in
-     * {@link android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute}
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @CardEmulation.ProtocolAndTechnologyRoute
-    public int getDefaultIsoDepRoute() {
-        return mDefaultIsoDepRoute;
-    }
-
-    /**
-     * Getter of the default off-host route.
-     * @return an integer defined in
-     * {@link android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute}
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @CardEmulation.ProtocolAndTechnologyRoute
-    public int getDefaultOffHostRoute() {
-        return mDefaultOffHostRoute;
-    }
-
-}
diff --git a/nfc/java/android/nfc/RoutingTableAidEntry.java b/nfc/java/android/nfc/RoutingTableAidEntry.java
deleted file mode 100644
index be94f9f..0000000
--- a/nfc/java/android/nfc/RoutingTableAidEntry.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-/**
- * Represents an Application ID (AID) entry in current routing table.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public class RoutingTableAidEntry extends NfcRoutingTableEntry {
-    private final String mValue;
-
-    /** @hide */
-    public RoutingTableAidEntry(int nfceeId, String value,
-            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
-        super(nfceeId, TYPE_AID, routeType);
-        this.mValue = value;
-    }
-
-    /**
-     * Gets AID value.
-     * @return String of AID
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @NonNull
-    public String getAid() {
-        return mValue;
-    }
-}
diff --git a/nfc/java/android/nfc/RoutingTableProtocolEntry.java b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
deleted file mode 100644
index a68d8c1..0000000
--- a/nfc/java/android/nfc/RoutingTableProtocolEntry.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Represents a protocol entry in current routing table.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public class RoutingTableProtocolEntry extends NfcRoutingTableEntry {
-    /**
-     * Protocol undetermined.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_UNDETERMINED = 0;
-    /**
-     * T1T Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_T1T = 1;
-    /**
-     * T2T Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_T2T = 2;
-    /**
-     * T3T Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_T3T = 3;
-    /**
-     * ISO-DEP Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_ISO_DEP = 4;
-    /**
-     * DEP Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_NFC_DEP = 5;
-    /**
-     * T5T Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_T5T = 6;
-    /**
-     * NDEF Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_NDEF = 7;
-    /**
-     * Unsupported Protocol
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int PROTOCOL_UNSUPPORTED = -1;
-
-    /**
-     *
-     * @hide
-     */
-    @IntDef(prefix = { "PROTOCOL_" }, value = {
-            PROTOCOL_UNDETERMINED,
-            PROTOCOL_T1T,
-            PROTOCOL_T2T,
-            PROTOCOL_T3T,
-            PROTOCOL_ISO_DEP,
-            PROTOCOL_NFC_DEP,
-            PROTOCOL_T5T,
-            PROTOCOL_NDEF,
-            PROTOCOL_UNSUPPORTED
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ProtocolValue {}
-
-    private final @ProtocolValue int mValue;
-
-    /** @hide */
-    public RoutingTableProtocolEntry(int nfceeId, @ProtocolValue int value,
-            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
-        super(nfceeId, TYPE_PROTOCOL, routeType);
-        this.mValue = value;
-    }
-
-    /**
-     * Gets Protocol value.
-     * @return Protocol defined in {@link ProtocolValue}
-     */
-    @ProtocolValue
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public int getProtocol() {
-        return mValue;
-    }
-
-    /** @hide */
-    @ProtocolValue
-    public static int protocolStringToInt(String protocolString) {
-        return switch (protocolString) {
-            case "PROTOCOL_T1T" -> PROTOCOL_T1T;
-            case "PROTOCOL_T2T" -> PROTOCOL_T2T;
-            case "PROTOCOL_T3T" -> PROTOCOL_T3T;
-            case "PROTOCOL_ISO_DEP" -> PROTOCOL_ISO_DEP;
-            case "PROTOCOL_NFC_DEP" -> PROTOCOL_NFC_DEP;
-            case "PROTOCOL_T5T" -> PROTOCOL_T5T;
-            case "PROTOCOL_NDEF" -> PROTOCOL_NDEF;
-            case "PROTOCOL_UNDETERMINED" -> PROTOCOL_UNDETERMINED;
-            default -> PROTOCOL_UNSUPPORTED;
-        };
-    }
-}
diff --git a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
deleted file mode 100644
index 06cc0a5..0000000
--- a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-/**
- * Represents a system code entry in current routing table, where system codes are two-byte values
- * used in NFC-F technology (a type of NFC communication) to identify specific
- * device configurations.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public class RoutingTableSystemCodeEntry extends NfcRoutingTableEntry {
-    private final byte[] mValue;
-
-    /** @hide */
-    public RoutingTableSystemCodeEntry(int nfceeId, byte[] value,
-            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
-        super(nfceeId, TYPE_SYSTEM_CODE, routeType);
-        this.mValue = value;
-    }
-
-    /**
-     * Gets system code value.
-     * @return Byte array of system code
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    @NonNull
-    public byte[] getSystemCode() {
-        return mValue;
-    }
-}
diff --git a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
deleted file mode 100644
index 86239ce..0000000
--- a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Represents a technology entry in current routing table.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public class RoutingTableTechnologyEntry extends NfcRoutingTableEntry {
-    /**
-     * Technology-A.
-     * <p>Tech-A is mostly used for payment and ticketing applications. It supports various
-     * Tag platforms including Type 1, Type 2 and Type 4A tags. </p>
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int TECHNOLOGY_A = 0;
-    /**
-     * Technology-B which is based on ISO/IEC 14443-3 standard.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int TECHNOLOGY_B = 1;
-    /**
-     * Technology-F.
-     * <p>Tech-F is a standard which supports Type 3 Tags and NFC-DEP protocol etc.</p>
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int TECHNOLOGY_F = 2;
-    /**
-     * Technology-V.
-     * <p>Tech-V is an NFC technology used for communication with passive tags that operate
-     * at a longer range than other NFC technologies. </p>
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int TECHNOLOGY_V = 3;
-    /**
-     * Unsupported technology
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public static final int TECHNOLOGY_UNSUPPORTED = -1;
-
-    /**
-     *
-     * @hide
-     */
-    @IntDef(prefix = { "TECHNOLOGY_" }, value = {
-            TECHNOLOGY_A,
-            TECHNOLOGY_B,
-            TECHNOLOGY_F,
-            TECHNOLOGY_V,
-            TECHNOLOGY_UNSUPPORTED
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface TechnologyValue{}
-
-    private final @TechnologyValue int mValue;
-
-    /** @hide */
-    public RoutingTableTechnologyEntry(int nfceeId, @TechnologyValue int value,
-            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
-        super(nfceeId, TYPE_TECHNOLOGY, routeType);
-        this.mValue = value;
-    }
-
-    /**
-     * Gets technology value.
-     * @return technology value
-     */
-    @TechnologyValue
-    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-    public int getTechnology() {
-        return mValue;
-    }
-
-    /** @hide */
-    @TechnologyValue
-    public static int techStringToInt(String tech) {
-        return switch (tech) {
-            case "TECHNOLOGY_A" -> TECHNOLOGY_A;
-            case "TECHNOLOGY_B" -> TECHNOLOGY_B;
-            case "TECHNOLOGY_F" -> TECHNOLOGY_F;
-            case "TECHNOLOGY_V" -> TECHNOLOGY_V;
-            default -> TECHNOLOGY_UNSUPPORTED;
-        };
-    }
-}
diff --git a/nfc/java/android/nfc/T4tNdefNfcee.java b/nfc/java/android/nfc/T4tNdefNfcee.java
deleted file mode 100644
index 05a30aa..0000000
--- a/nfc/java/android/nfc/T4tNdefNfcee.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.annotation.WorkerThread;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This class is used for performing T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
- * NFCEE (NFC Execution Environment) operations.
- * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
- * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
- * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public final class T4tNdefNfcee {
-    private static final String TAG = "NdefNfcee";
-    static T4tNdefNfcee sNdefNfcee;
-
-    private T4tNdefNfcee() {
-    }
-
-    /**
-     * Helper to get an instance of this class.
-     *
-     * @return
-     * @hide
-     */
-    @NonNull
-    public static T4tNdefNfcee getInstance() {
-        if (sNdefNfcee == null) {
-            sNdefNfcee = new T4tNdefNfcee();
-        }
-        return sNdefNfcee;
-    }
-
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data is successful.
-     */
-    public static final int WRITE_DATA_SUCCESS = 0;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to unknown reasons.
-     */
-    public static final int WRITE_DATA_ERROR_INTERNAL = -1;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to ongoing rf activity.
-     */
-    public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to Nfc off.
-     */
-    public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to invalid file id.
-     */
-    public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to invalid length.
-     */
-    public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to core connection create failure.
-     */
-    public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6;
-    /**
-     * Return flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to empty payload.
-     */
-    public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7;
-    /**
-     * Returns flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail due to invalid ndef format.
-     */
-    public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8;
-    /**
-     * Returns flag for {@link #writeData(int, byte[])}.
-     * It indicates write data fail if a concurrent NDEF NFCEE operation is ongoing.
-     */
-    public static final int WRITE_DATA_ERROR_DEVICE_BUSY = -9;
-
-    /**
-     * Possible return values for {@link #writeData(int, byte[])}.
-     *
-     * @hide
-     */
-    @IntDef(prefix = { "WRITE_DATA_" }, value = {
-        WRITE_DATA_SUCCESS,
-        WRITE_DATA_ERROR_INTERNAL,
-        WRITE_DATA_ERROR_RF_ACTIVATED,
-        WRITE_DATA_ERROR_NFC_NOT_ON,
-        WRITE_DATA_ERROR_INVALID_FILE_ID,
-        WRITE_DATA_ERROR_INVALID_LENGTH,
-        WRITE_DATA_ERROR_CONNECTION_FAILED,
-        WRITE_DATA_ERROR_EMPTY_PAYLOAD,
-        WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED,
-        WRITE_DATA_ERROR_DEVICE_BUSY,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface WriteDataStatus{}
-
-    /**
-     * This API performs writes of T4T data to NFCEE.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread.</p>
-     * <p>Applications must send complete Ndef Message payload, do not need to fragment
-     * the payload, it will be automatically fragmented and defragmented by
-     * {@link #writeData} if it exceeds max message length limits</p>
-     *
-     * @param fileId File id (Refer NFC Forum Type 4 Tag Specification
-     *               Section 4.2 File Identifiers and Access Conditions
-     *               for more information) to which to write.
-     * @param data   This should be valid Ndef Message format.
-     *               Refer to Nfc forum NDEF specification NDEF Message section
-     * @return status of the operation.
-     * @hide
-     */
-    @SystemApi
-    @WorkerThread
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public @WriteDataStatus int writeData(@IntRange(from = 0, to = 65535) int fileId,
-            @NonNull byte[] data) {
-        return NfcAdapter.callServiceReturn(() ->
-                NfcAdapter.sNdefNfceeService.writeData(fileId, data), WRITE_DATA_ERROR_INTERNAL);
-    }
-
-    /**
-     * This API performs reading of T4T content of Nfcee.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread.</p>
-     *
-     * @param fileId File Id (Refer
-     *               Section 4.2 File Identifiers and Access Conditions
-     *               for more information) from which to read.
-     * @return - Returns complete Ndef message if success
-     *           Refer to Nfc forum NDEF specification NDEF Message section
-     * @throws IllegalStateException if read fails because the fileId is invalid
-     *         or if a concurrent operation is in progress.
-     * @hide
-     */
-    @SystemApi
-    @WorkerThread
-    @NonNull
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public byte[] readData(@IntRange(from = 0, to = 65535) int fileId) {
-        return NfcAdapter.callServiceReturn(() ->
-            NfcAdapter.sNdefNfceeService.readData(fileId), null);
-    }
-
-    /**
-     * Return flag for {@link #clearNdefData()}.
-     * It indicates clear data is successful.
-     */
-    public static final int CLEAR_DATA_SUCCESS = 1;
-     /**
-     * Return flag for {@link #clearNdefData()}.
-     * It indicates clear data failed due to internal error while processing the clear.
-     */
-    public static final int CLEAR_DATA_FAILED_INTERNAL = 0;
-    /**
-     * Return flag for {@link #clearNdefData()}.
-     * It indicates clear data failed  if a concurrent NDEF NFCEE operation is ongoing.
-     */
-    public static final int CLEAR_DATA_FAILED_DEVICE_BUSY = -1;
-
-
-    /**
-     * Possible return values for {@link #clearNdefData()}.
-     *
-     * @hide
-     */
-    @IntDef(prefix = { "CLEAR_DATA_" }, value = {
-        CLEAR_DATA_SUCCESS,
-        CLEAR_DATA_FAILED_INTERNAL,
-        CLEAR_DATA_FAILED_DEVICE_BUSY,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ClearDataStatus{}
-
-    /**
-     * This API will set all the T4T NDEF NFCEE data to zero.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread.
-     *
-     * <p>This API can be called regardless of NDEF file lock state.
-     * </p>
-     * @return status of the operation
-     *
-     * @hide
-     */
-    @SystemApi
-    @WorkerThread
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public @ClearDataStatus int clearData() {
-        return NfcAdapter.callServiceReturn(() ->
-            NfcAdapter.sNdefNfceeService.clearNdefData(), CLEAR_DATA_FAILED_INTERNAL);
-    }
-
-    /**
-     * Returns whether NDEF NFCEE operation is ongoing or not.
-     *
-     * @return true if NDEF NFCEE operation is ongoing, else false.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean isOperationOngoing() {
-        return NfcAdapter.callServiceReturn(() ->
-            NfcAdapter.sNdefNfceeService.isNdefOperationOngoing(), false);
-    }
-
-    /**
-     * This Api is to check the status of NDEF NFCEE emulation feature is
-     * supported or not.
-     *
-     * @return true if NDEF NFCEE emulation feature is supported, else false.
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public boolean isSupported() {
-        return NfcAdapter.callServiceReturn(() ->
-            NfcAdapter.sNdefNfceeService.isNdefNfceeEmulationSupported(), false);
-    }
-
-    /**
-     * This API performs reading of T4T NDEF NFCEE CC file content.
-     *
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
-     *
-     * @return Returns CC file content if success or null if failed to read.
-     * @throws IllegalStateException if the device is busy.
-     * @hide
-     */
-    @SystemApi
-    @WorkerThread
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @Nullable
-    public T4tNdefNfceeCcFileInfo readCcfile() {
-        return NfcAdapter.callServiceReturn(() ->
-            NfcAdapter.sNdefNfceeService.readCcfile(), null);
-    }
-}
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
deleted file mode 100644
index f72f74e..0000000
--- a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-parcelable T4tNdefNfceeCcFileInfo;
-
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
deleted file mode 100644
index ce67f8f..0000000
--- a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This class is used to represence T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
- * NFCEE (NFC Execution Environment) CC (Capability Container) File data.
- * The CC file stores metadata about the T4T tag being emulated.
- *
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public final class T4tNdefNfceeCcFileInfo implements Parcelable {
-    /**
-     * Indicates the size of this capability container (called “CC File”)<p>
-     */
-    private int mCcLength;
-    /**
-     * Indicates the mapping specification version<p>
-     */
-    private int mVersion;
-    /**
-     * Indicates the NDEF File Identifier<p>
-     */
-    private int mFileId;
-    /**
-     * Indicates the maximum Max NDEF file size<p>
-     */
-    private int mMaxSize;
-    /**
-     * Indicates the read access condition<p>
-     */
-    private boolean mIsReadAllowed;
-    /**
-     * Indicates the write access condition<p>
-     */
-    private boolean mIsWriteAllowed;
-
-    /**
-     * Constructor to be used by NFC service and internal classes.
-     * @hide
-     */
-    public T4tNdefNfceeCcFileInfo(int cclen, int version,
-                      int ndefFileId, int ndefMaxSize,
-                      boolean isReadAllowed, boolean isWriteAllowed) {
-        mCcLength = cclen;
-        mVersion = version;
-        mFileId = ndefFileId;
-        mMaxSize = ndefMaxSize;
-        mIsReadAllowed = isReadAllowed;
-        mIsWriteAllowed = isWriteAllowed;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mCcLength);
-        dest.writeInt(mVersion);
-        dest.writeInt(mFileId);
-        dest.writeInt(mMaxSize);
-        dest.writeBoolean(mIsReadAllowed);
-        dest.writeBoolean(mIsWriteAllowed);
-    }
-
-    /**
-     * Indicates the size of this capability container (called “CC File”).
-     *
-     * @return length of the CC file.
-     */
-    @IntRange(from = 0xf, to = 0x7fff)
-    public int getCcFileLength() {
-        return mCcLength;
-    }
-
-    /**
-     * T4T tag mapping version 2.0.
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
-     */
-    public static final int VERSION_2_0 = 0x20;
-    /**
-     * T4T tag mapping version 2.0.
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
-     */
-    public static final int VERSION_3_0 = 0x30;
-
-    /**
-     * Possible return values for {@link #getVersion()}.
-     * @hide
-     */
-    @IntDef(prefix = { "VERSION_" }, value = {
-            VERSION_2_0,
-            VERSION_3_0,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Version{}
-
-    /**
-     * Indicates the mapping version of the T4T tag supported.
-     *
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.5" for more details.
-     *
-     * @return version of the specification
-     */
-    @Version
-    public int getVersion() {
-        return mVersion;
-    }
-
-    /**
-     * Indicates the NDEF File Identifier. This is the identifier used in the last invocation of
-     * {@link T4tNdefNfcee#writeData(int, byte[])}
-     *
-     * @return FileId of the data stored or -1 if no data is present.
-     */
-    @IntRange(from = -1, to = 65535)
-    public int getFileId() {
-        return mFileId;
-    }
-
-    /**
-     * Indicates the maximum size of T4T NDEF data that can be written to the NFCEE.
-     *
-     * @return max size of the contents.
-     */
-    @IntRange(from = 0x5, to = 0x7fff)
-    public int getMaxSize() {
-        return mMaxSize;
-    }
-
-    /**
-     * Indicates the read access condition.
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
-     * @return boolean true if read access is allowed, otherwise false.
-     */
-    public boolean isReadAllowed() {
-        return mIsReadAllowed;
-    }
-
-    /**
-     * Indicates the write access condition.
-     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
-     * @return boolean if write access is allowed, otherwise false.
-     */
-    public boolean isWriteAllowed() {
-        return mIsWriteAllowed;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final @NonNull Parcelable.Creator<T4tNdefNfceeCcFileInfo> CREATOR =
-            new Parcelable.Creator<>() {
-                @Override
-                public T4tNdefNfceeCcFileInfo createFromParcel(Parcel in) {
-
-                    // NdefNfceeCcFileInfo fields
-                    int cclen = in.readInt();
-                    int version = in.readInt();
-                    int ndefFileId = in.readInt();
-                    int ndefMaxSize = in.readInt();
-                    boolean isReadAllowed = in.readBoolean();
-                    boolean isWriteAllowed = in.readBoolean();
-
-                    return new T4tNdefNfceeCcFileInfo(cclen, version,
-                            ndefFileId, ndefMaxSize,
-                            isReadAllowed, isWriteAllowed);
-                }
-
-                @Override
-                public T4tNdefNfceeCcFileInfo[] newArray(int size) {
-                    return new T4tNdefNfceeCcFileInfo[size];
-                }
-            };
-}
diff --git a/nfc/java/android/nfc/Tag.aidl b/nfc/java/android/nfc/Tag.aidl
deleted file mode 100644
index 312261e..0000000
--- a/nfc/java/android/nfc/Tag.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc;
-
-parcelable Tag;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/Tag.java b/nfc/java/android/nfc/Tag.java
deleted file mode 100644
index 500038f..0000000
--- a/nfc/java/android/nfc/Tag.java
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.nfc.tech.IsoDep;
-import android.nfc.tech.MifareClassic;
-import android.nfc.tech.MifareUltralight;
-import android.nfc.tech.Ndef;
-import android.nfc.tech.NdefFormatable;
-import android.nfc.tech.NfcA;
-import android.nfc.tech.NfcB;
-import android.nfc.tech.NfcBarcode;
-import android.nfc.tech.NfcF;
-import android.nfc.tech.NfcV;
-import android.nfc.tech.TagTechnology;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-
-/**
- * Represents an NFC tag that has been discovered.
- * <p>
- * {@link Tag} is an immutable object that represents the state of a NFC tag at
- * the time of discovery. It can be used as a handle to {@link TagTechnology} classes
- * to perform advanced operations, or directly queried for its ID via {@link #getId} and the
- * set of technologies it contains via {@link #getTechList}. Arrays passed to and
- * returned by this class are <em>not</em> cloned, so be careful not to modify them.
- * <p>
- * A new tag object is created every time a tag is discovered (comes into range), even
- * if it is the same physical tag. If a tag is removed and then returned into range, then
- * only the most recent tag object can be successfully used to create a {@link TagTechnology}.
- *
- * <h3>Tag Dispatch</h3>
- * When a tag is discovered, a {@link Tag} object is created and passed to a
- * single activity via the {@link NfcAdapter#EXTRA_TAG} extra in an
- * {@link android.content.Intent} via {@link Context#startActivity}. A four stage dispatch is used
- * to select the
- * most appropriate activity to handle the tag. The Android OS executes each stage in order,
- * and completes dispatch as soon as a single matching activity is found. If there are multiple
- * matching activities found at any one stage then the Android activity chooser dialog is shown
- * to allow the user to select the activity to receive the tag.
- *
- * <p>The Tag dispatch mechanism was designed to give a high probability of dispatching
- * a tag to the correct activity without showing the user an activity chooser dialog.
- * This is important for NFC interactions because they are very transient -- if a user has to
- * move the Android device to choose an application then the connection will likely be broken.
- *
- * <h4>1. Foreground activity dispatch</h4>
- * A foreground activity that has called
- * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} is
- * given priority. See the documentation on
- * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} for
- * its usage.
- * <h4>2. NDEF data dispatch</h4>
- * If the tag contains NDEF data the system inspects the first {@link NdefRecord} in the first
- * {@link NdefMessage}. If the record is a URI, SmartPoster, or MIME data
- * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_NDEF_DISCOVERED}. For URI
- * and SmartPoster records the URI is put into the intent's data field. For MIME records the MIME
- * type is put in the intent's type field. This allows activities to register to be launched only
- * when data they know how to handle is present on a tag. This is the preferred method of handling
- * data on a tag since NDEF data can be stored on many types of tags and doesn't depend on a
- * specific tag technology. 
- * See {@link NfcAdapter#ACTION_NDEF_DISCOVERED} for more detail. If the tag does not contain
- * NDEF data, or if no activity is registered
- * for {@link NfcAdapter#ACTION_NDEF_DISCOVERED} with a matching data URI or MIME type then dispatch
- * moves to stage 3.
- * <h4>3. Tag Technology dispatch</h4>
- * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_TECH_DISCOVERED} to
- * dispatch the tag to an activity that can handle the technologies present on the tag.
- * Technologies are defined as sub-classes of {@link TagTechnology}, see the package
- * {@link android.nfc.tech}. The Android OS looks for an activity that can handle one or
- * more technologies in the tag. See {@link NfcAdapter#ACTION_TECH_DISCOVERED} for more detail.
- * <h4>4. Fall-back dispatch</h4>
- * If no activity has been matched then {@link Context#startActivity} is called with
- * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. This is intended as a fall-back mechanism.
- * See {@link NfcAdapter#ACTION_TAG_DISCOVERED}.
- *
- * <h3>NFC Tag Background</h3>
- * An NFC tag is a passive NFC device, powered by the NFC field of this Android device while
- * it is in range. Tag's can come in many forms, such as stickers, cards, key fobs, or
- * even embedded in a more sophisticated device.
- * <p>
- * Tags can have a wide range of capabilities. Simple tags just offer read/write semantics,
- * and contain some one time
- * programmable areas to make read-only. More complex tags offer math operations
- * and per-sector access control and authentication. The most sophisticated tags
- * contain operating environments allowing complex interactions with the
- * code executing on the tag. Use {@link TagTechnology} classes to access a broad
- * range of capabilities available in NFC tags.
- * <p>
- */
-public final class Tag implements Parcelable {
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    final byte[] mId;
-    final int[] mTechList;
-    final String[] mTechStringList;
-    final Bundle[] mTechExtras;
-    final int mServiceHandle;  // for use by NFC service, 0 indicates a mock
-    final long mCookie;        // for accessibility checking
-    final INfcTag mTagService; // interface to NFC service, will be null if mock tag
-
-    int mConnectedTechnology;
-
-    /**
-     * Hidden constructor to be used by NFC service and internal classes.
-     * @hide
-     */
-    public Tag(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle,
-            long cookie, INfcTag tagService) {
-        if (techList == null) {
-            throw new IllegalArgumentException("rawTargets cannot be null");
-        }
-        mId = id;
-        mTechList = Arrays.copyOf(techList, techList.length);
-        mTechStringList = generateTechStringList(techList);
-        // Ensure mTechExtras is as long as mTechList
-        mTechExtras = Arrays.copyOf(techListExtras, techList.length);
-        mServiceHandle = serviceHandle;
-        mCookie = cookie;
-        mTagService = tagService;
-        mConnectedTechnology = -1;
-
-        if (tagService == null) {
-            return;
-        }
-    }
-
-    /**
-     * Construct a mock Tag.
-     * <p>This is an application constructed tag, so NfcAdapter methods on this Tag may fail
-     * with {@link IllegalArgumentException} since it does not represent a physical Tag.
-     * <p>This constructor might be useful for mock testing.
-     * @param id The tag identifier, can be null
-     * @param techList must not be null
-     * @return freshly constructed tag
-     * @hide
-     */
-    public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras,
-            long cookie) {
-        // set serviceHandle to 0 and tagService to null to indicate mock tag
-        return new Tag(id, techList, techListExtras, 0, cookie, null);
-    }
-
-    private String[] generateTechStringList(int[] techList) {
-        final int size = techList.length;
-        String[] strings = new String[size];
-        for (int i = 0; i < size; i++) {
-            switch (techList[i]) {
-                case TagTechnology.ISO_DEP:
-                    strings[i] = IsoDep.class.getName();
-                    break;
-                case TagTechnology.MIFARE_CLASSIC:
-                    strings[i] = MifareClassic.class.getName();
-                    break;
-                case TagTechnology.MIFARE_ULTRALIGHT:
-                    strings[i] = MifareUltralight.class.getName();
-                    break;
-                case TagTechnology.NDEF:
-                    strings[i] = Ndef.class.getName();
-                    break;
-                case TagTechnology.NDEF_FORMATABLE:
-                    strings[i] = NdefFormatable.class.getName();
-                    break;
-                case TagTechnology.NFC_A:
-                    strings[i] = NfcA.class.getName();
-                    break;
-                case TagTechnology.NFC_B:
-                    strings[i] = NfcB.class.getName();
-                    break;
-                case TagTechnology.NFC_F:
-                    strings[i] = NfcF.class.getName();
-                    break;
-                case TagTechnology.NFC_V:
-                    strings[i] = NfcV.class.getName();
-                    break;
-                case TagTechnology.NFC_BARCODE:
-                    strings[i] = NfcBarcode.class.getName();
-                    break;
-                default:
-                    throw new IllegalArgumentException("Unknown tech type " + techList[i]);
-            }
-        }
-        return strings;
-    }
-
-    static int[] getTechCodesFromStrings(String[] techStringList) throws IllegalArgumentException {
-        if (techStringList == null) {
-            throw new IllegalArgumentException("List cannot be null");
-        }
-        int[] techIntList = new int[techStringList.length];
-        HashMap<String, Integer> stringToCodeMap = getTechStringToCodeMap();
-        for (int i = 0; i < techStringList.length; i++) {
-            Integer code = stringToCodeMap.get(techStringList[i]);
-
-            if (code == null) {
-                throw new IllegalArgumentException("Unknown tech type " + techStringList[i]);
-            }
-
-            techIntList[i] = code.intValue();
-        }
-        return techIntList;
-    }
-
-    private static HashMap<String, Integer> getTechStringToCodeMap() {
-        HashMap<String, Integer> techStringToCodeMap = new HashMap<String, Integer>();
-
-        techStringToCodeMap.put(IsoDep.class.getName(), TagTechnology.ISO_DEP);
-        techStringToCodeMap.put(MifareClassic.class.getName(), TagTechnology.MIFARE_CLASSIC);
-        techStringToCodeMap.put(MifareUltralight.class.getName(), TagTechnology.MIFARE_ULTRALIGHT);
-        techStringToCodeMap.put(Ndef.class.getName(), TagTechnology.NDEF);
-        techStringToCodeMap.put(NdefFormatable.class.getName(), TagTechnology.NDEF_FORMATABLE);
-        techStringToCodeMap.put(NfcA.class.getName(), TagTechnology.NFC_A);
-        techStringToCodeMap.put(NfcB.class.getName(), TagTechnology.NFC_B);
-        techStringToCodeMap.put(NfcF.class.getName(), TagTechnology.NFC_F);
-        techStringToCodeMap.put(NfcV.class.getName(), TagTechnology.NFC_V);
-        techStringToCodeMap.put(NfcBarcode.class.getName(), TagTechnology.NFC_BARCODE);
-
-        return techStringToCodeMap;
-    }
-
-    /**
-     * For use by NfcService only.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public int getServiceHandle() {
-        return mServiceHandle;
-    }
-
-    /**
-     * For use by NfcService only.
-     * @hide
-     */
-    public int[] getTechCodeList() {
-        return mTechList;
-    }
-
-    /**
-     * Get the Tag Identifier (if it has one).
-     * <p>The tag identifier is a low level serial number, used for anti-collision
-     * and identification.
-     * <p> Most tags have a stable unique identifier
-     * (UID), but some tags will generate a random ID every time they are discovered
-     * (RID), and there are some tags with no ID at all (the byte array will be zero-sized).
-     * <p> The size and format of an ID is specific to the RF technology used by the tag.
-     * <p> This function retrieves the ID as determined at discovery time, and does not
-     * perform any further RF communication or block.
-     * @return ID as byte array, never null
-     */
-    public byte[] getId() {
-        return mId;
-    }
-
-    /**
-     * Get the technologies available in this tag, as fully qualified class names.
-     * <p>
-     * A technology is an implementation of the {@link TagTechnology} interface,
-     * and can be instantiated by calling the static <code>get(Tag)</code>
-     * method on the implementation with this Tag. The {@link TagTechnology}
-     * object can then be used to perform advanced, technology-specific operations on a tag.
-     * <p>
-     * Android defines a mandatory set of technologies that must be correctly
-     * enumerated by all Android NFC devices, and an optional
-     * set of proprietary technologies.
-     * See {@link TagTechnology} for more details.
-     * <p>
-     * The ordering of the returned array is undefined and should not be relied upon.
-     * @return an array of fully-qualified {@link TagTechnology} class-names.
-     */
-    public String[] getTechList() {
-        return mTechStringList;
-    }
-
-    /**
-     * Rediscover the technologies available on this tag.
-     * <p>
-     * The technologies that are available on a tag may change due to
-     * operations being performed on a tag. For example, formatting a
-     * tag as NDEF adds the {@link Ndef} technology. The {@link rediscover}
-     * method reenumerates the available technologies on the tag
-     * and returns a new {@link Tag} object containing these technologies.
-     * <p>
-     * You may not be connected to any of this {@link Tag}'s technologies
-     * when calling this method.
-     * This method guarantees that you will be returned the same Tag
-     * if it is still in the field.
-     * <p>May cause RF activity and may block. Must not be called
-     * from the main application thread. A blocked call will be canceled with
-     * {@link IOException} by calling {@link #close} from another thread.
-     * <p>Does not remove power from the RF field, so a tag having a random
-     * ID should not change its ID.
-     * @return the rediscovered tag object.
-     * @throws IOException if the tag cannot be rediscovered
-     * @hide
-     */
-    // TODO See if we need TagLostException
-    // TODO Unhide for ICS
-    // TODO Update documentation to make sure it matches with the final
-    //      implementation.
-    public Tag rediscover() throws IOException {
-        if (getConnectedTechnology() != -1) {
-            throw new IllegalStateException("Close connection to the technology first!");
-        }
-
-        if (mTagService == null) {
-            throw new IOException("Mock tags don't support this operation.");
-        }
-        try {
-            Tag newTag = mTagService.rediscover(getServiceHandle());
-            if (newTag != null) {
-                return newTag;
-            } else {
-                throw new IOException("Failed to rediscover tag");
-            }
-        } catch (RemoteException e) {
-            throw new IOException("NFC service dead");
-        }
-    }
-
-
-    /** @hide */
-    public boolean hasTech(int techType) {
-        for (int tech : mTechList) {
-            if (tech == techType) return true;
-        }
-        return false;
-    }
-
-    /** @hide */
-    public Bundle getTechExtras(int tech) {
-        int pos = -1;
-        for (int idx = 0; idx < mTechList.length; idx++) {
-          if (mTechList[idx] == tech) {
-              pos = idx;
-              break;
-          }
-        }
-        if (pos < 0) {
-            return null;
-        }
-
-        return mTechExtras[pos];
-    }
-
-    /** @hide */
-    @UnsupportedAppUsage
-    public INfcTag getTagService() {
-        if (mTagService == null) {
-            return null;
-        }
-
-        try {
-            if (!mTagService.isTagUpToDate(mCookie)) {
-                String id_str = "";
-                for (int i = 0; i < mId.length; i++) {
-                    id_str = id_str + String.format("%02X ", mId[i]);
-                }
-                String msg = "Permission Denial: Tag ( ID: " + id_str + ") is out of date";
-                throw new SecurityException(msg);
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        }
-        return mTagService;
-    }
-
-    /**
-     * Human-readable description of the tag, for debugging.
-     */
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("TAG: Tech [");
-        String[] techList = getTechList();
-        int length = techList.length;
-        for (int i = 0; i < length; i++) {
-            sb.append(techList[i]);
-            if (i < length - 1) {
-                sb.append(", ");
-            }
-        }
-        sb.append("]");
-        return sb.toString();
-    }
-
-    /*package*/ static byte[] readBytesWithNull(Parcel in) {
-        int len = in.readInt();
-        byte[] result = null;
-        if (len >= 0) {
-            result = new byte[len];
-            in.readByteArray(result);
-        }
-        return result;
-    }
-
-    /*package*/ static void writeBytesWithNull(Parcel out, byte[] b) {
-        if (b == null) {
-            out.writeInt(-1);
-            return;
-        }
-        out.writeInt(b.length);
-        out.writeByteArray(b);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        // Null mTagService means this is a mock tag
-        int isMock = (mTagService == null)?1:0;
-
-        writeBytesWithNull(dest, mId);
-        dest.writeInt(mTechList.length);
-        dest.writeIntArray(mTechList);
-        dest.writeTypedArray(mTechExtras, 0);
-        dest.writeInt(mServiceHandle);
-        dest.writeLong(mCookie);
-        dest.writeInt(isMock);
-        if (isMock == 0) {
-            dest.writeStrongBinder(mTagService.asBinder());
-        }
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<Tag> CREATOR =
-            new Parcelable.Creator<Tag>() {
-        @Override
-        public Tag createFromParcel(Parcel in) {
-            INfcTag tagService;
-
-            // Tag fields
-            byte[] id = Tag.readBytesWithNull(in);
-            int[] techList = new int[in.readInt()];
-            in.readIntArray(techList);
-            Bundle[] techExtras = in.createTypedArray(Bundle.CREATOR);
-            int serviceHandle = in.readInt();
-            long cookie = in.readLong();
-            int isMock = in.readInt();
-            if (isMock == 0) {
-                tagService = INfcTag.Stub.asInterface(in.readStrongBinder());
-            }
-            else {
-                tagService = null;
-            }
-
-            return new Tag(id, techList, techExtras, serviceHandle, cookie, tagService);
-        }
-
-        @Override
-        public Tag[] newArray(int size) {
-            return new Tag[size];
-        }
-    };
-
-    /**
-     * For internal use only.
-     *
-     * @hide
-     */
-    public synchronized boolean setConnectedTechnology(int technology) {
-        if (mConnectedTechnology != -1) {
-            return false;
-        }
-        mConnectedTechnology = technology;
-        return true;
-    }
-
-    /**
-     * For internal use only.
-     *
-     * @hide
-     */
-    public int getConnectedTechnology() {
-        return mConnectedTechnology;
-    }
-
-    /**
-     * For internal use only.
-     *
-     * @hide
-     */
-    public void setTechnologyDisconnected() {
-        mConnectedTechnology = -1;
-    }
-}
diff --git a/nfc/java/android/nfc/TagLostException.java b/nfc/java/android/nfc/TagLostException.java
deleted file mode 100644
index 1981d7c..0000000
--- a/nfc/java/android/nfc/TagLostException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2011, 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 android.nfc;
-
-import java.io.IOException;
-
-public class TagLostException extends IOException {
-    public TagLostException() {
-        super();
-    }
-
-    public TagLostException(String message) {
-        super(message);
-    }
-}
diff --git a/nfc/java/android/nfc/TechListParcel.aidl b/nfc/java/android/nfc/TechListParcel.aidl
deleted file mode 100644
index 92e646f..0000000
--- a/nfc/java/android/nfc/TechListParcel.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2011 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 android.nfc;
-
-parcelable TechListParcel;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/TechListParcel.java b/nfc/java/android/nfc/TechListParcel.java
deleted file mode 100644
index 9f01559..0000000
--- a/nfc/java/android/nfc/TechListParcel.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2011 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 android.nfc;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/** @hide */
-public class TechListParcel implements Parcelable {
-
-    private String[][] mTechLists;
-
-    public TechListParcel(String[]... strings) {
-        mTechLists = strings;
-    }
-
-    public String[][] getTechLists() {
-        return mTechLists;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        int count = mTechLists.length;
-        dest.writeInt(count);
-        for (int i = 0; i < count; i++) {
-            String[] techList = mTechLists[i];
-            dest.writeStringArray(techList);
-        }
-    }
-
-    public static final @android.annotation.NonNull Creator<TechListParcel> CREATOR = new Creator<TechListParcel>() {
-        @Override
-        public TechListParcel createFromParcel(Parcel source) {
-            int count = source.readInt();
-            String[][] techLists = new String[count][];
-            for (int i = 0; i < count; i++) {
-                techLists[i] = source.createStringArray();
-            }
-            return new TechListParcel(techLists);
-        }
-
-        @Override
-        public TechListParcel[] newArray(int size) {
-            return new TechListParcel[size];
-        }
-    };
-}
diff --git a/nfc/java/android/nfc/TransceiveResult.aidl b/nfc/java/android/nfc/TransceiveResult.aidl
deleted file mode 100644
index 98f92ee..0000000
--- a/nfc/java/android/nfc/TransceiveResult.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2011 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 android.nfc;
-
-parcelable TransceiveResult;
diff --git a/nfc/java/android/nfc/TransceiveResult.java b/nfc/java/android/nfc/TransceiveResult.java
deleted file mode 100644
index 7992094..0000000
--- a/nfc/java/android/nfc/TransceiveResult.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011, 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 android.nfc;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.io.IOException;
-
-/**
- * Class used to pipe transceive result from the NFC service.
- *
- * @hide
- */
-public final class TransceiveResult implements Parcelable {
-    public static final int RESULT_SUCCESS = 0;
-    public static final int RESULT_FAILURE = 1;
-    public static final int RESULT_TAGLOST = 2;
-    public static final int RESULT_EXCEEDED_LENGTH = 3;
-
-    final int mResult;
-    final byte[] mResponseData;
-
-    public TransceiveResult(final int result, final byte[] data) {
-        mResult = result;
-        mResponseData = data;
-    }
-
-    public byte[] getResponseOrThrow() throws IOException {
-        switch (mResult) {
-            case RESULT_SUCCESS:
-                return mResponseData;
-            case RESULT_TAGLOST:
-                throw new TagLostException("Tag was lost.");
-            case RESULT_EXCEEDED_LENGTH:
-                throw new IOException("Transceive length exceeds supported maximum");
-            default:
-                throw new IOException("Transceive failed");
-        }
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mResult);
-        if (mResult == RESULT_SUCCESS) {
-            dest.writeInt(mResponseData.length);
-            dest.writeByteArray(mResponseData);
-        }
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<TransceiveResult> CREATOR =
-            new Parcelable.Creator<TransceiveResult>() {
-        @Override
-        public TransceiveResult createFromParcel(Parcel in) {
-            int result = in.readInt();
-            byte[] responseData;
-
-            if (result == RESULT_SUCCESS) {
-                int responseLength = in.readInt();
-                responseData = new byte[responseLength];
-                in.readByteArray(responseData);
-            } else {
-                responseData = null;
-            }
-            return new TransceiveResult(result, responseData);
-        }
-
-        @Override
-        public TransceiveResult[] newArray(int size) {
-            return new TransceiveResult[size];
-        }
-    };
-
-}
diff --git a/nfc/java/android/nfc/WlcListenerDeviceInfo.aidl b/nfc/java/android/nfc/WlcListenerDeviceInfo.aidl
deleted file mode 100644
index 7f2ca54..0000000
--- a/nfc/java/android/nfc/WlcListenerDeviceInfo.aidl
+++ /dev/null
@@ -1,19 +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 android.nfc;
-
-parcelable WlcListenerDeviceInfo;
diff --git a/nfc/java/android/nfc/WlcListenerDeviceInfo.java b/nfc/java/android/nfc/WlcListenerDeviceInfo.java
deleted file mode 100644
index 45315f8..0000000
--- a/nfc/java/android/nfc/WlcListenerDeviceInfo.java
+++ /dev/null
@@ -1,145 +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 android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.FloatRange;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Contains information of the nfc wireless charging listener device information.
- */
-@FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-public final class WlcListenerDeviceInfo implements Parcelable {
-    /**
-     * Device is currently not connected with any WlcListenerDevice.
-     */
-    public static final int STATE_DISCONNECTED = 1;
-
-    /**
-     * Device is currently connected with a WlcListenerDevice and is charging it.
-     */
-    public static final int STATE_CONNECTED_CHARGING = 2;
-
-    /**
-     * Device is currently connected with a WlcListenerDevice without charging it.
-     */
-    public static final int STATE_CONNECTED_DISCHARGING = 3;
-
-    /**
-     * Possible states from {@link #getState}.
-     * @hide
-     */
-    @IntDef(prefix = { "STATE_" }, value = {
-            STATE_DISCONNECTED,
-            STATE_CONNECTED_CHARGING,
-            STATE_CONNECTED_DISCHARGING
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface WlcListenerState{}
-
-    private int mProductId;
-    private double mTemperature;
-    private double mBatteryLevel;
-    private int mState;
-
-     /**
-     * Create a new object containing wlc listener information.
-     *
-     * @param productId code for the device vendor
-     * @param temperature current temperature
-     * @param batteryLevel current battery level
-     * @param state current state
-     */
-    public WlcListenerDeviceInfo(int productId, double temperature, double batteryLevel,
-            @WlcListenerState int state) {
-        this.mProductId = productId;
-        this.mTemperature = temperature;
-        this.mBatteryLevel = batteryLevel;
-        this.mState = state;
-    }
-
-    /**
-     * ProductId of the WLC listener device.
-     * @return integer that is converted from USI Stylus VendorID[11:0].
-     */
-    public int getProductId() {
-        return mProductId;
-    }
-
-    /**
-     * Temperature of the WLC listener device.
-     * @return the value represents the temperature in °C.
-     */
-    public double getTemperature() {
-        return mTemperature;
-    }
-
-    /**
-     * BatteryLevel of the WLC listener device.
-     * @return battery level in percentage [0-100]
-     */
-    public @FloatRange(from = 0.0, to = 100.0) double getBatteryLevel() {
-        return mBatteryLevel;
-    }
-
-    /**
-     * State of the WLC listener device.
-     */
-    public @WlcListenerState int getState() {
-        return mState;
-    }
-
-    private WlcListenerDeviceInfo(Parcel in) {
-        this.mProductId = in.readInt();
-        this.mTemperature = in.readDouble();
-        this.mBatteryLevel = in.readDouble();
-        this.mState = in.readInt();
-    }
-
-    public static final @NonNull Parcelable.Creator<WlcListenerDeviceInfo> CREATOR =
-            new Parcelable.Creator<WlcListenerDeviceInfo>() {
-                @Override
-                public WlcListenerDeviceInfo createFromParcel(Parcel in) {
-                    return new WlcListenerDeviceInfo(in);
-                }
-
-                @Override
-                public WlcListenerDeviceInfo[] newArray(int size) {
-                    return new WlcListenerDeviceInfo[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mProductId);
-        dest.writeDouble(mTemperature);
-        dest.writeDouble(mBatteryLevel);
-        dest.writeInt(mState);
-    }
-}
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
deleted file mode 100644
index fee9c5b..0000000
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ /dev/null
@@ -1,1497 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.nfc.cardemulation;
-
-import android.Manifest;
-import android.annotation.CallbackExecutor;
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresFeature;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
-import android.annotation.UserHandleAware;
-import android.annotation.UserIdInt;
-import android.app.Activity;
-import android.app.role.RoleManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.nfc.ComponentNameAndUser;
-import android.nfc.Constants;
-import android.nfc.Flags;
-import android.nfc.INfcCardEmulation;
-import android.nfc.INfcEventCallback;
-import android.nfc.NfcAdapter;
-import android.os.Build;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
-import android.telephony.SubscriptionManager;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.HashMap;
-import java.util.HexFormat;
-import java.util.List;
-import java.util.Locale;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-import java.util.regex.Pattern;
-
-/**
- * This class can be used to query the state of
- * NFC card emulation services.
- *
- * For a general introduction into NFC card emulation,
- * please read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
- * NFC card emulation developer guide</a>.</p>
- *
- * <p class="note">Use of this class requires the
- * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} to be present
- * on the device.
- */
-public final class CardEmulation {
-    private static final Pattern AID_PATTERN = Pattern.compile("[0-9A-Fa-f]{10,32}\\*?\\#?");
-    private static final Pattern PLPF_PATTERN = Pattern.compile("[0-9A-Fa-f,\\?,\\*\\.]*");
-
-    static final String TAG = "CardEmulation";
-
-    /**
-     * Activity action: ask the user to change the default
-     * card emulation service for a certain category. This will
-     * show a dialog that asks the user whether they want to
-     * replace the current default service with the service
-     * identified with the ComponentName specified in
-     * {@link #EXTRA_SERVICE_COMPONENT}, for the category
-     * specified in {@link #EXTRA_CATEGORY}. There is an optional
-     * extra field using {@link Intent#EXTRA_USER} to specify
-     * the {@link UserHandle} of the user that owns the app.
-     *
-     * @deprecated Please use {@link android.app.role.RoleManager#createRequestRoleIntent(String)}
-     * with {@link android.app.role.RoleManager#ROLE_WALLET} parameter
-     * and {@link Activity#startActivityForResult(Intent, int)} instead.
-     */
-    @Deprecated
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_CHANGE_DEFAULT =
-            "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
-
-    /**
-     * The category extra for {@link #ACTION_CHANGE_DEFAULT}.
-     *
-     * @see #ACTION_CHANGE_DEFAULT
-     */
-    public static final String EXTRA_CATEGORY = "category";
-
-    /**
-     * The service {@link ComponentName} object passed in as an
-     * extra for {@link #ACTION_CHANGE_DEFAULT}.
-     *
-     * @see #ACTION_CHANGE_DEFAULT
-     */
-    public static final String EXTRA_SERVICE_COMPONENT = "component";
-
-    /**
-     * Category used for NFC payment services.
-     */
-    public static final String CATEGORY_PAYMENT = "payment";
-
-    /**
-     * Category that can be used for all other card emulation
-     * services.
-     */
-    public static final String CATEGORY_OTHER = "other";
-
-    /**
-     * Return value for {@link #getSelectionModeForCategory(String)}.
-     *
-     * <p>In this mode, the user has set a default service for this
-     *    category.
-     *
-     * <p>When using ISO-DEP card emulation with {@link HostApduService}
-     *    or {@link OffHostApduService}, if a remote NFC device selects
-     *    any of the Application IDs (AIDs)
-     *    that the default service has registered in this category,
-     *    that service will automatically be bound to to handle
-     *    the transaction.
-     */
-    public static final int SELECTION_MODE_PREFER_DEFAULT = 0;
-
-    /**
-     * Return value for {@link #getSelectionModeForCategory(String)}.
-     *
-     * <p>In this mode, when using ISO-DEP card emulation with {@link HostApduService}
-     *    or {@link OffHostApduService}, whenever an Application ID (AID) of this category
-     *    is selected, the user is asked which service they want to use to handle
-     *    the transaction, even if there is only one matching service.
-     */
-    public static final int SELECTION_MODE_ALWAYS_ASK = 1;
-
-    /**
-     * Return value for {@link #getSelectionModeForCategory(String)}.
-     *
-     * <p>In this mode, when using ISO-DEP card emulation with {@link HostApduService}
-     *    or {@link OffHostApduService}, the user will only be asked to select a service
-     *    if the Application ID (AID) selected by the reader has been registered by multiple
-     *    services. If there is only one service that has registered for the AID,
-     *    that service will be invoked directly.
-     */
-    public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2;
-    /**
-     * Route to Device Host (DH).
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DH = 0;
-    /**
-     * Route to eSE.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE = 1;
-    /**
-     * Route to UICC.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC = 2;
-
-    /**
-     * Route to the default value in config file.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT = 3;
-
-    /**
-     * Route unset.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET = -1;
-
-    /**
-     * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
-     * succeeded.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
-    public static final int SET_SERVICE_ENABLED_STATUS_OK = 0;
-
-    /**
-     * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
-     * failed due to the unsupported feature.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
-    public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED = 1;
-
-    /**
-     * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
-     * failed due to the invalid service.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
-    public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE = 2;
-
-    /**
-     * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
-     * failed due to the service is already set to the requested status.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
-    public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET = 3;
-
-    /**
-     * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
-     * failed due to unknown error.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
-    public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR = 4;
-
-    /**
-     * Status code returned by {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
-     * @hide
-     */
-    @IntDef(prefix = "SET_SERVICE_ENABLED_STATUS_", value = {
-            SET_SERVICE_ENABLED_STATUS_OK,
-            SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED,
-            SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE,
-            SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET,
-            SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SetServiceEnabledStatusCode {}
-
-    /**
-     * Property name used to indicate that an application wants to allow associated services
-     * to share the same AID routing priority when this application is the role holder.
-     * <p>
-     * Example:
-     * <pre>
-     *     {@code
-     *     <application>
-     *       ...
-     *       <property android:name="android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY"
-     *         android:value="true"/>
-     *     </application>
-     *     }
-     * </pre>
-     */
-    @FlaggedApi(Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES)
-    public static final String PROPERTY_ALLOW_SHARED_ROLE_PRIORITY =
-            "android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY";
-
-    static boolean sIsInitialized = false;
-    static HashMap<Context, CardEmulation> sCardEmus = new HashMap<Context, CardEmulation>();
-    static INfcCardEmulation sService;
-
-    final Context mContext;
-
-    private CardEmulation(Context context, INfcCardEmulation service) {
-        mContext = context.getApplicationContext();
-        sService = service;
-    }
-
-    /**
-     * Helper to get an instance of this class.
-     *
-     * @param adapter A reference to an NfcAdapter object.
-     * @return
-     */
-    public static synchronized CardEmulation getInstance(NfcAdapter adapter) {
-        if (adapter == null) throw new NullPointerException("NfcAdapter is null");
-        Context context = adapter.getContext();
-        if (context == null) {
-            Log.e(TAG, "NfcAdapter context is null.");
-            throw new UnsupportedOperationException();
-        }
-        if (!sIsInitialized) {
-            PackageManager pm = context.getPackageManager();
-            if (pm == null) {
-                Log.e(TAG, "Cannot get PackageManager");
-                throw new UnsupportedOperationException();
-            }
-            if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
-                Log.e(TAG, "This device does not support card emulation");
-                throw new UnsupportedOperationException();
-            }
-            sIsInitialized = true;
-        }
-        CardEmulation manager = sCardEmus.get(context);
-        if (manager == null) {
-            // Get card emu service
-            INfcCardEmulation service = adapter.getCardEmulationService();
-            if (service == null) {
-                Log.e(TAG, "This device does not implement the INfcCardEmulation interface.");
-                throw new UnsupportedOperationException();
-            }
-            manager = new CardEmulation(context, service);
-            sCardEmus.put(context, manager);
-        }
-        return manager;
-    }
-
-    /**
-     * Allows an application to query whether a service is currently
-     * the default service to handle a card emulation category.
-     *
-     * <p>Note that if {@link #getSelectionModeForCategory(String)}
-     * returns {@link #SELECTION_MODE_ALWAYS_ASK} or {@link #SELECTION_MODE_ASK_IF_CONFLICT},
-     * this method will always return false. That is because in these
-     * selection modes a default can't be set at the category level. For categories where
-     * the selection mode is {@link #SELECTION_MODE_ALWAYS_ASK} or
-     * {@link #SELECTION_MODE_ASK_IF_CONFLICT}, use
-     * {@link #isDefaultServiceForAid(ComponentName, String)} to determine whether a service
-     * is the default for a specific AID.
-     *
-     * @param service The ComponentName of the service
-     * @param category The category
-     * @return whether service is currently the default service for the category.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     */
-    public boolean isDefaultServiceForCategory(ComponentName service, String category) {
-        return callServiceReturn(() ->
-            sService.isDefaultServiceForCategory(
-                mContext.getUser().getIdentifier(), service, category), false);
-    }
-
-    /**
-     *
-     * Allows an application to query whether a service is currently
-     * the default handler for a specified ISO7816-4 Application ID.
-     *
-     * @param service The ComponentName of the service
-     * @param aid The ISO7816-4 Application ID
-     * @return whether the service is the default handler for the specified AID
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     */
-    public boolean isDefaultServiceForAid(ComponentName service, String aid) {
-        return callServiceReturn(() ->
-            sService.isDefaultServiceForAid(
-                mContext.getUser().getIdentifier(), service, aid), false);
-    }
-
-    /**
-     * <p>
-     * Returns whether the user has allowed AIDs registered in the
-     * specified category to be handled by a service that is preferred
-     * by the foreground application, instead of by a pre-configured default.
-     *
-     * Foreground applications can set such preferences using the
-     * {@link #setPreferredService(Activity, ComponentName)} method.
-     * <p class="note">
-     * Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, this method will always
-     * return true.
-     *
-     * @param category The category, e.g. {@link #CATEGORY_PAYMENT}
-     * @return whether AIDs in the category can be handled by a service
-     *         specified by the foreground app.
-     */
-    @SuppressWarnings("NonUserGetterCalled")
-    public boolean categoryAllowsForegroundPreference(String category) {
-        Context contextAsUser = mContext.createContextAsUser(
-                UserHandle.of(UserHandle.myUserId()), 0);
-
-        RoleManager roleManager = contextAsUser.getSystemService(RoleManager.class);
-        if (roleManager.isRoleAvailable(RoleManager.ROLE_WALLET)) {
-            return true;
-        }
-
-        if (CATEGORY_PAYMENT.equals(category)) {
-            boolean preferForeground = false;
-            try {
-                preferForeground = Settings.Secure.getInt(
-                        contextAsUser.getContentResolver(),
-                        Constants.SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND) != 0;
-            } catch (SettingNotFoundException e) {
-            }
-            return preferForeground;
-        } else {
-            // Allowed for all other categories
-            return true;
-        }
-    }
-
-    /**
-     * Returns the service selection mode for the passed in category.
-     * Valid return values are:
-     * <p>{@link #SELECTION_MODE_PREFER_DEFAULT} the user has requested a default
-     *    service for this category, which will be preferred.
-     * <p>{@link #SELECTION_MODE_ALWAYS_ASK} the user has requested to be asked
-     *    every time what service they would like to use in this category.
-     * <p>{@link #SELECTION_MODE_ASK_IF_CONFLICT} the user will only be asked
-     *    to pick a service if there is a conflict.
-     *
-     * <p class="note">
-     * Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, the default service defined
-     * by the holder of {@link android.app.role.RoleManager#ROLE_WALLET} and is category agnostic.
-     *
-     * @param category The category, for example {@link #CATEGORY_PAYMENT}
-     * @return the selection mode for the passed in category
-     */
-    public int getSelectionModeForCategory(String category) {
-        if (CATEGORY_PAYMENT.equals(category)) {
-            boolean paymentRegistered = callServiceReturn(() ->
-                    sService.isDefaultPaymentRegistered(), false);
-            if (paymentRegistered) {
-                return SELECTION_MODE_PREFER_DEFAULT;
-            } else {
-                return SELECTION_MODE_ALWAYS_ASK;
-            }
-        } else {
-            return SELECTION_MODE_ASK_IF_CONFLICT;
-        }
-    }
-    /**
-     * Sets whether when this service becomes the preferred service, if the NFC stack
-     * should enable observe mode or disable observe mode. The default is to not enable observe
-     * mode when a service either the foreground default service or the default payment service so
-     * not calling this method will preserve that behavior.
-     *
-     * @param service The component name of the service
-     * @param enable Whether the service should default to observe mode or not
-     * @return whether the change was successful.
-     */
-    @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
-    public boolean setShouldDefaultToObserveModeForService(@NonNull ComponentName service,
-            boolean enable) {
-        return callServiceReturn(() ->
-            sService.setShouldDefaultToObserveModeForService(
-                mContext.getUser().getIdentifier(), service, enable), false);
-    }
-
-    /**
-     * Register a polling loop filter (PLF) for a HostApduService and indicate whether it should
-     * auto-transact or not.  The PLF can be sequence of an
-     * even number of at least 2 hexadecimal numbers (0-9, A-F or a-f), representing a series of
-     * bytes. When non-standard polling loop frame matches this sequence exactly, it may be
-     * delivered to {@link HostApduService#processPollingFrames(List)}.  If auto-transact
-     * is set to true and this service is currently preferred or there are no other services
-     * registered for this filter then observe mode will also be disabled.
-     * @param service The HostApduService to register the filter for
-     * @param pollingLoopFilter The filter to register
-     * @param autoTransact true to have the NFC stack automatically disable observe mode and allow
-     *         transactions to proceed when this filter matches, false otherwise
-     * @return true if the filter was registered, false otherwise
-     * @throws IllegalArgumentException if the passed in string doesn't parse to at least one byte
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public boolean registerPollingLoopFilterForService(@NonNull ComponentName service,
-            @NonNull String pollingLoopFilter, boolean autoTransact) {
-        final String pollingLoopFilterV = validatePollingLoopFilter(pollingLoopFilter);
-        return callServiceReturn(() ->
-            sService.registerPollingLoopFilterForService(
-                mContext.getUser().getIdentifier(), service, pollingLoopFilterV, autoTransact),
-            false);
-    }
-
-    /**
-     * Unregister a polling loop filter (PLF) for a HostApduService. If the PLF had previously been
-     * registered via {@link #registerPollingLoopFilterForService(ComponentName, String, boolean)}
-     * for this service it will be removed.
-     * @param service The HostApduService to unregister the filter for
-     * @param pollingLoopFilter The filter to unregister
-     * @return true if the filter was removed, false otherwise
-     * @throws IllegalArgumentException if the passed in string doesn't parse to at least one byte
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public boolean removePollingLoopFilterForService(@NonNull ComponentName service,
-            @NonNull String pollingLoopFilter) {
-        final String pollingLoopFilterV = validatePollingLoopFilter(pollingLoopFilter);
-        return callServiceReturn(() ->
-            sService.removePollingLoopFilterForService(
-                mContext.getUser().getIdentifier(), service, pollingLoopFilterV), false);
-    }
-
-
-    /**
-     * Register a polling loop pattern filter (PLPF) for a HostApduService and indicate whether it
-     * should auto-transact or not. The pattern may include the characters 0-9 and A-F as well as
-     * the regular expression operators `.`, `?` and `*`. When the beginning of anon-standard
-     * polling loop frame matches this sequence exactly, it may be delivered to
-     * {@link HostApduService#processPollingFrames(List)}. If auto-transact is set to true and this
-     * service is currently preferred or there are no other services registered for this filter
-     * then observe mode will also be disabled.
-     * @param service The HostApduService to register the filter for
-     * @param pollingLoopPatternFilter The pattern filter to register, must to be compatible with
-     *         {@link java.util.regex.Pattern#compile(String)} and only contain hexadecimal numbers
-     *         and `.`, `?` and `*` operators
-     * @param autoTransact true to have the NFC stack automatically disable observe mode and allow
-     *         transactions to proceed when this filter matches, false otherwise
-     * @return true if the filter was registered, false otherwise
-     * @throws IllegalArgumentException if the filter containst elements other than hexadecimal
-     *         numbers and `.`, `?` and `*` operators
-     * @throws java.util.regex.PatternSyntaxException if the regex syntax is invalid
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public boolean registerPollingLoopPatternFilterForService(@NonNull ComponentName service,
-            @NonNull String pollingLoopPatternFilter, boolean autoTransact) {
-        final String pollingLoopPatternFilterV =
-            validatePollingLoopPatternFilter(pollingLoopPatternFilter);
-        return callServiceReturn(() ->
-            sService.registerPollingLoopPatternFilterForService(
-                mContext.getUser().getIdentifier(), service, pollingLoopPatternFilterV,
-                autoTransact),
-            false);
-    }
-
-    /**
-     * Unregister a polling loop pattern filter (PLPF) for a HostApduService. If the PLF had
-     * previously been registered via
-     * {@link #registerPollingLoopFilterForService(ComponentName, String, boolean)} for this
-     * service it will be removed.
-     * @param service The HostApduService to unregister the filter for
-     * @param pollingLoopPatternFilter The filter to unregister, must to be compatible with
-     *         {@link java.util.regex.Pattern#compile(String)} and only contain hexadecimal numbers
-     *         and`.`, `?` and `*` operators
-     * @return true if the filter was removed, false otherwise
-     * @throws IllegalArgumentException if the filter containst elements other than hexadecimal
-     *         numbers and `.`, `?` and `*` operators
-     * @throws java.util.regex.PatternSyntaxException if the regex syntax is invalid
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public boolean removePollingLoopPatternFilterForService(@NonNull ComponentName service,
-            @NonNull String pollingLoopPatternFilter) {
-        final String pollingLoopPatternFilterV =
-            validatePollingLoopPatternFilter(pollingLoopPatternFilter);
-        return callServiceReturn(() ->
-            sService.removePollingLoopPatternFilterForService(
-                mContext.getUser().getIdentifier(), service, pollingLoopPatternFilterV), false);
-    }
-
-    /**
-     * Registers a list of AIDs for a specific category for the
-     * specified service.
-     *
-     * <p>If a list of AIDs for that category was previously
-     * registered for this service (either statically
-     * through the manifest, or dynamically by using this API),
-     * that list of AIDs will be replaced with this one.
-     *
-     * <p>Note that you can only register AIDs for a service that
-     * is running under the same UID as the caller of this API. Typically
-     * this means you need to call this from the same
-     * package as the service itself, though UIDs can also
-     * be shared between packages using shared UIDs.
-     *
-     * @param service The component name of the service
-     * @param category The category of AIDs to be registered
-     * @param aids A list containing the AIDs to be registered
-     * @return whether the registration was successful.
-     */
-    public boolean registerAidsForService(ComponentName service, String category,
-            List<String> aids) {
-        final AidGroup aidGroup = new AidGroup(aids, category);
-        return callServiceReturn(() ->
-            sService.registerAidGroupForService(
-                mContext.getUser().getIdentifier(), service, aidGroup), false);
-    }
-
-    /**
-     * Unsets the off-host Secure Element for the given service.
-     *
-     * <p>Note that this will only remove Secure Element that was dynamically
-     * set using the {@link #setOffHostForService(ComponentName, String)}
-     * and resets it to a value that was statically assigned using manifest.
-     *
-     * <p>Note that you can only unset off-host SE for a service that
-     * is running under the same UID as the caller of this API. Typically
-     * this means you need to call this from the same
-     * package as the service itself, though UIDs can also
-     * be shared between packages using shared UIDs.
-     *
-     * @param service The component name of the service
-     * @return whether the registration was successful.
-     */
-    @RequiresPermission(android.Manifest.permission.NFC)
-    @NonNull
-    public boolean unsetOffHostForService(@NonNull ComponentName service) {
-        return callServiceReturn(() ->
-            sService.unsetOffHostForService(
-                mContext.getUser().getIdentifier(), service), false);
-    }
-
-    /**
-     * Sets the off-host Secure Element for the given service.
-     *
-     * <p>If off-host SE was initially set (either statically
-     * through the manifest, or dynamically by using this API),
-     * it will be replaced with this one. All AIDs registered by
-     * this service will be re-routed to this Secure Element if
-     * successful. AIDs that was statically assigned using manifest
-     * will re-route to off-host SE that stated in manifest after NFC
-     * toggle.
-     *
-     * <p>Note that you can only set off-host SE for a service that
-     * is running under the same UID as the caller of this API. Typically
-     * this means you need to call this from the same
-     * package as the service itself, though UIDs can also
-     * be shared between packages using shared UIDs.
-     *
-     * <p>Registeration will be successful only if the Secure Element
-     * exists on the device.
-     *
-     * @param service The component name of the service
-     * @param offHostSecureElement Secure Element to register the AID to. Only accept strings with
-     *                             prefix SIM or prefix eSE.
-     *                             Ref: GSMA TS.26 - NFC Handset Requirements
-     *                             TS26_NFC_REQ_069: For UICC, Secure Element Name SHALL be
-     *                                               SIM[smartcard slot]
-     *                                               (e.g. SIM/SIM1, SIM2… SIMn).
-     *                             TS26_NFC_REQ_070: For embedded SE, Secure Element Name SHALL be
-     *                                               eSE[number]
-     *                                               (e.g. eSE/eSE1, eSE2, etc.).
-     * @return whether the registration was successful.
-     */
-    @RequiresPermission(android.Manifest.permission.NFC)
-    @NonNull
-    public boolean setOffHostForService(@NonNull ComponentName service,
-            @NonNull String offHostSecureElement) {
-        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
-        if (adapter == null || offHostSecureElement == null) {
-            return false;
-        }
-
-        List<String> validSE = adapter.getSupportedOffHostSecureElements();
-        if ((offHostSecureElement.startsWith("eSE") && !validSE.contains("eSE"))
-                || (offHostSecureElement.startsWith("SIM") && !validSE.contains("SIM"))) {
-            return false;
-        }
-
-        if (!offHostSecureElement.startsWith("eSE") && !offHostSecureElement.startsWith("SIM")) {
-            return false;
-        }
-
-        if (offHostSecureElement.equals("eSE")) {
-            offHostSecureElement = "eSE1";
-        } else if (offHostSecureElement.equals("SIM")) {
-            offHostSecureElement = "SIM1";
-        }
-        final String offHostSecureElementV = new String(offHostSecureElement);
-        return callServiceReturn(() ->
-            sService.setOffHostForService(
-                mContext.getUser().getIdentifier(), service, offHostSecureElementV), false);
-    }
-
-    /**
-     * Retrieves the currently registered AIDs for the specified
-     * category for a service.
-     *
-     * <p>Note that this will only return AIDs that were dynamically
-     * registered using {@link #registerAidsForService(ComponentName, String, List)}
-     * method. It will *not* return AIDs that were statically registered
-     * in the manifest.
-     *
-     * @param service The component name of the service
-     * @param category The category for which the AIDs were registered,
-     *                 e.g. {@link #CATEGORY_PAYMENT}
-     * @return The list of AIDs registered for this category, or null if it couldn't be found.
-     */
-    public List<String> getAidsForService(ComponentName service, String category) {
-        AidGroup group = callServiceReturn(() ->
-               sService.getAidGroupForService(
-                   mContext.getUser().getIdentifier(), service, category), null);
-        return (group != null ? group.getAids() : null);
-    }
-
-    /**
-     * Removes a previously registered list of AIDs for the specified category for the
-     * service provided.
-     *
-     * <p>Note that this will only remove AIDs that were dynamically
-     * registered using the {@link #registerAidsForService(ComponentName, String, List)}
-     * method. It will *not* remove AIDs that were statically registered in
-     * the manifest. If dynamically registered AIDs are removed using
-     * this method, and a statically registered AID group for the same category
-     * exists in the manifest, the static AID group will become active again.
-     *
-     * @param service The component name of the service
-     * @param category The category of the AIDs to be removed, e.g. {@link #CATEGORY_PAYMENT}
-     * @return whether the group was successfully removed.
-     */
-    public boolean removeAidsForService(ComponentName service, String category) {
-        return callServiceReturn(() ->
-            sService.removeAidGroupForService(
-                mContext.getUser().getIdentifier(), service, category), false);
-    }
-
-    /**
-     * Allows a foreground application to specify which card emulation service
-     * should be preferred while a specific Activity is in the foreground.
-     *
-     * <p>The specified Activity must currently be in resumed state. A good
-     * paradigm is to call this method in your {@link Activity#onResume}, and to call
-     * {@link #unsetPreferredService(Activity)} in your {@link Activity#onPause}.
-     *
-     * <p>This method call will fail in two specific scenarios:
-     * <ul>
-     * <li> If the service registers one or more AIDs in the {@link #CATEGORY_PAYMENT}
-     * category, but the user has indicated that foreground apps are not allowed
-     * to override the default payment service.
-     * <li> If the service registers one or more AIDs in the {@link #CATEGORY_OTHER}
-     * category that are also handled by the default payment service, and the
-     * user has indicated that foreground apps are not allowed to override the
-     * default payment service.
-     * </ul>
-     *
-     * <p> Use {@link #categoryAllowsForegroundPreference(String)} to determine
-     * whether foreground apps can override the default payment service.
-     *
-     * <p>Note that this preference is not persisted by the OS, and hence must be
-     * called every time the Activity is resumed.
-     *
-     * @param activity The activity which prefers this service to be invoked
-     * @param service The service to be preferred while this activity is in the foreground
-     * @return whether the registration was successful
-     */
-    public boolean setPreferredService(Activity activity, ComponentName service) {
-        // Verify the activity is in the foreground before calling into NfcService
-        if (activity == null || service == null) {
-            throw new NullPointerException("activity or service or category is null");
-        }
-        return callServiceReturn(() -> sService.setPreferredService(service), false);
-    }
-
-    /**
-     * Unsets the preferred service for the specified Activity.
-     *
-     * <p>Note that the specified Activity must still be in resumed
-     * state at the time of this call. A good place to call this method
-     * is in your {@link Activity#onPause} implementation.
-     *
-     * @param activity The activity which the service was registered for
-     * @return true when successful
-     */
-    public boolean unsetPreferredService(Activity activity) {
-        if (activity == null) {
-            throw new NullPointerException("activity is null");
-        }
-        return callServiceReturn(() -> sService.unsetPreferredService(), false);
-    }
-
-    /**
-     * Some devices may allow an application to register all
-     * AIDs that starts with a certain prefix, e.g.
-     * "A000000004*" to register all MasterCard AIDs.
-     *
-     * Use this method to determine whether this device
-     * supports registering AID prefixes.
-     *
-     * @return whether AID prefix registering is supported on this device.
-     */
-    public boolean supportsAidPrefixRegistration() {
-        return callServiceReturn(() -> sService.supportsAidPrefixRegistration(), false);
-    }
-
-    /**
-     * Retrieves the registered AIDs for the preferred payment service.
-     *
-     * @return The list of AIDs registered for this category, or null if it couldn't be found.
-     */
-    @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
-    @Nullable
-    public List<String> getAidsForPreferredPaymentService() {
-        ApduServiceInfo serviceInfo = callServiceReturn(() ->
-                sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null);
-        return (serviceInfo != null ? serviceInfo.getAids() : null);
-    }
-
-    /**
-     * Retrieves the route destination for the preferred payment service.
-     *
-     * <p class="note">
-     * Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, the preferred payment service
-     * no longer exists and is replaced by {@link android.app.role.RoleManager#ROLE_WALLET}. This
-     * will return the route for one of the services registered by the role holder (if any). If
-     * there are multiple services registered, it is unspecified which of those will be used to
-     * determine the route.
-     *
-     * @return The route destination secure element name of the preferred payment service.
-     *         HCE payment: "Host"
-     *         OffHost payment: 1. String with prefix SIM or prefix eSE string.
-     *                             Ref: GSMA TS.26 - NFC Handset Requirements
-     *                             TS26_NFC_REQ_069: For UICC, Secure Element Name SHALL be
-     *                                               SIM[smartcard slot]
-     *                                               (e.g. SIM/SIM1, SIM2… SIMn).
-     *                             TS26_NFC_REQ_070: For embedded SE, Secure Element Name SHALL be
-     *                                               eSE[number]
-     *                                               (e.g. eSE/eSE1, eSE2, etc.).
-     *                          2. "OffHost" if the payment service does not specify secure element
-     *                             name.
-     */
-    @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
-    @Nullable
-    public String getRouteDestinationForPreferredPaymentService() {
-        ApduServiceInfo serviceInfo = callServiceReturn(() ->
-                sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null);
-        if (serviceInfo != null) {
-            if (!serviceInfo.isOnHost()) {
-                return serviceInfo.getOffHostSecureElement() == null ?
-                        "OffHost" : serviceInfo.getOffHostSecureElement();
-            }
-            return "Host";
-        }
-        return null;
-    }
-
-    /**
-     * Returns a user-visible description of the preferred payment service.
-     *
-     * <p class="note">
-     * Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, the preferred payment service
-     * no longer exists and is replaced by {@link android.app.role.RoleManager#ROLE_WALLET}. This
-     * will return the description for one of the services registered by the role holder (if any).
-     * If there are multiple services registered, it is unspecified which of those will be used
-     * to obtain the service description here.
-     *
-     * @return the preferred payment service description
-     */
-    @RequiresPermission(Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
-    @Nullable
-    public CharSequence getDescriptionForPreferredPaymentService() {
-        ApduServiceInfo serviceInfo = callServiceReturn(() ->
-                sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null);
-        return (serviceInfo != null ? serviceInfo.getDescription() : null);
-    }
-
-    /**
-     * @hide
-     */
-    public boolean setDefaultServiceForCategory(ComponentName service, String category) {
-        return callServiceReturn(() ->
-                sService.setDefaultServiceForCategory(
-                    mContext.getUser().getIdentifier(), service, category), false);
-    }
-
-    /**
-     * @hide
-     */
-    public boolean setDefaultForNextTap(ComponentName service) {
-        return callServiceReturn(() ->
-                sService.setDefaultForNextTap(
-                    mContext.getUser().getIdentifier(), service), false);
-    }
-
-    /**
-     * @hide
-     */
-    public boolean setDefaultForNextTap(int userId, ComponentName service) {
-        return callServiceReturn(() ->
-                sService.setDefaultForNextTap(userId, service), false);
-    }
-
-    /**
-     * @hide
-     */
-    public List<ApduServiceInfo> getServices(String category) {
-        return callServiceReturn(() ->
-                sService.getServices(
-                    mContext.getUser().getIdentifier(), category), null);
-    }
-
-    /**
-     * Retrieves list of services registered of the provided category for the provided user.
-     *
-     * @param category Category string, one of {@link #CATEGORY_PAYMENT} or {@link #CATEGORY_OTHER}
-     * @param userId the user handle of the user whose information is being requested.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
-    @NonNull
-    public List<ApduServiceInfo> getServices(@NonNull String category, @UserIdInt int userId) {
-        return callServiceReturn(() ->
-                sService.getServices(userId, category), null);
-    }
-
-    /**
-     * Tests the validity of the polling loop filter.
-     * @param pollingLoopFilter The polling loop filter to test.
-     *
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static @NonNull String validatePollingLoopFilter(@NonNull String pollingLoopFilter) {
-        // Verify hex characters
-        byte[] plfBytes = HexFormat.of().parseHex(pollingLoopFilter);
-        if (plfBytes.length == 0) {
-            throw new IllegalArgumentException(
-                "Polling loop filter must contain at least one byte.");
-        }
-        return HexFormat.of().withUpperCase().formatHex(plfBytes);
-    }
-
-    /**
-     * Tests the validity of the polling loop pattern filter.
-     * @param pollingLoopPatternFilter The polling loop filter to test.
-     *
-     * @hide
-     */
-    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static @NonNull String validatePollingLoopPatternFilter(
-        @NonNull String pollingLoopPatternFilter) {
-        // Verify hex characters
-        if (!PLPF_PATTERN.matcher(pollingLoopPatternFilter).matches()) {
-            throw new IllegalArgumentException(
-                "Polling loop pattern filters may only contain hexadecimal numbers, ?s and *s");
-        }
-        return Pattern.compile(pollingLoopPatternFilter.toUpperCase(Locale.ROOT)).toString();
-    }
-
-    /**
-     * A valid AID according to ISO/IEC 7816-4:
-     * <ul>
-     * <li>Has >= 5 bytes and <=16 bytes (>=10 hex chars and <= 32 hex chars)
-     * <li>Consist of only hex characters
-     * <li>Additionally, we allow an asterisk at the end, to indicate
-     *     a prefix
-     * <li>Additinally we allow an (#) at symbol at the end, to indicate
-     *     a subset
-     * </ul>
-     *
-     * @hide
-     */
-    public static boolean isValidAid(String aid) {
-        if (aid == null)
-            return false;
-
-        // If a prefix/subset AID, the total length must be odd (even # of AID chars + '*')
-        if ((aid.endsWith("*") || aid.endsWith("#")) && ((aid.length() % 2) == 0)) {
-            Log.e(TAG, "AID " + aid + " is not a valid AID.");
-            return false;
-        }
-
-        // If not a prefix/subset AID, the total length must be even (even # of AID chars)
-        if ((!(aid.endsWith("*") || aid.endsWith("#"))) && ((aid.length() % 2) != 0)) {
-            Log.e(TAG, "AID " + aid + " is not a valid AID.");
-            return false;
-        }
-
-        // Verify hex characters
-        if (!AID_PATTERN.matcher(aid).matches()) {
-            Log.e(TAG, "AID " + aid + " is not a valid AID.");
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Allows to set or unset preferred service (category other) to avoid AID Collision. The user
-     * should use corresponding context using {@link Context#createContextAsUser(UserHandle, int)}
-     *
-     * @param service The ComponentName of the service
-     * @param status  true to enable, false to disable
-     * @return status code defined in {@link SetServiceEnabledStatusCode}
-     *
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @SetServiceEnabledStatusCode
-    public int setServiceEnabledForCategoryOther(@NonNull ComponentName service,
-            boolean status) {
-        return callServiceReturn(() ->
-                sService.setServiceEnabledForCategoryOther(mContext.getUser().getIdentifier(),
-                        service, status), SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR);
-    }
-
-    /** @hide */
-    @IntDef(prefix = "PROTOCOL_AND_TECHNOLOGY_ROUTE_",
-            value = {
-                    PROTOCOL_AND_TECHNOLOGY_ROUTE_DH,
-                    PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE,
-                    PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC,
-                    PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET,
-                    PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ProtocolAndTechnologyRoute {}
-
-    /**
-     * Setting NFC controller routing table, which includes Protocol Route and Technology Route,
-     * while this Activity is in the foreground.
-     *
-     * The parameter set to {@link #PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET}
-     * can be used to keep current values for that entry. Either
-     * Protocol Route or Technology Route should be override when calling this API, otherwise
-     * throw {@link IllegalArgumentException}.
-     * <p>
-     * Example usage in an Activity that requires to set proto route to "ESE" and keep tech route:
-     * <pre>
-     * protected void onResume() {
-     *     mNfcAdapter.overrideRoutingTable(
-     *         this, {@link #PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE},
-     *         {@link #PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET});
-     * }</pre>
-     * </p>
-     * Also activities must call {@link #recoverRoutingTable(Activity)}
-     * when it goes to the background. Only the package of the
-     * currently preferred service (the service set as preferred by the current foreground
-     * application via {@link CardEmulation#setPreferredService(Activity, ComponentName)} or the
-     * current Default Wallet Role Holder {@link RoleManager#ROLE_WALLET}),
-     * otherwise a call to this method will fail and throw {@link SecurityException}.
-     * @param activity The Activity that requests NFC controller routing table to be changed.
-     * @param protocol ISO-DEP route destination, where the possible inputs are defined
-     *                 in {@link ProtocolAndTechnologyRoute}.
-     * @param technology Tech-A, Tech-B and Tech-F route destination, where the possible inputs
-     *                   are defined in {@link ProtocolAndTechnologyRoute}
-     * @throws SecurityException if the caller is not the preferred NFC service
-     * @throws IllegalArgumentException if the activity is not resumed or the caller is not in the
-     * foreground.
-     * <p>
-     * This is a high risk API and only included to support mainline effort
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public void overrideRoutingTable(
-            @NonNull Activity activity, @ProtocolAndTechnologyRoute int protocol,
-            @ProtocolAndTechnologyRoute int technology) {
-        if (!activity.isResumed()) {
-            throw new IllegalArgumentException("Activity must be resumed.");
-        }
-        String protocolRoute = routeIntToString(protocol);
-        String technologyRoute = routeIntToString(technology);
-        callService(() ->
-                sService.overrideRoutingTable(
-                        mContext.getUser().getIdentifier(),
-                        protocolRoute,
-                        technologyRoute,
-                        mContext.getPackageName()));
-    }
-
-    /**
-     * Restore the NFC controller routing table,
-     * which was changed by {@link #overrideRoutingTable(Activity, int, int)}
-     *
-     * @param activity The Activity that requested NFC controller routing table to be changed.
-     * @throws IllegalArgumentException if the caller is not in the foreground.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
-    public void recoverRoutingTable(@NonNull Activity activity) {
-        if (!activity.isResumed()) {
-            throw new IllegalArgumentException("Activity must be resumed.");
-        }
-        callService(() ->
-                sService.recoverRoutingTable(
-                    mContext.getUser().getIdentifier()));
-    }
-
-    /**
-     * Is EUICC supported as a Secure Element EE which supports off host card emulation.
-     *
-     * @return true if the device supports EUICC for off host card emulation, false otherwise.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public boolean isEuiccSupported() {
-        return callServiceReturn(() -> sService.isEuiccSupported(), false);
-    }
-
-    /**
-     * Setting the default subscription ID succeeded.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0;
-
-    /**
-     * Setting the default subscription ID failed because the subscription ID is invalid.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1;
-
-    /**
-     * Setting the default subscription ID failed because there was an internal error processing
-     * the request. For ex: NFC service died in the middle of handling the API.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR = 2;
-
-    /**
-     * Setting the default subscription ID failed because this feature is not supported on the
-     * device.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3;
-
-    /**
-     * Setting the default subscription ID failed because of unknown error.
-     * @hide
-     */
-    @SystemApi
-    @FlaggedApi(Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public static final int SET_SUBSCRIPTION_ID_STATUS_UNKNOWN = -1;
-
-    /** @hide */
-    @IntDef(prefix = "SET_SUBSCRIPTION_ID_STATUS_",
-            value = {
-                    SET_SUBSCRIPTION_ID_STATUS_SUCCESS,
-                    SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID,
-                    SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR,
-                    SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED,
-                    SET_SUBSCRIPTION_ID_STATUS_UNKNOWN
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SetSubscriptionIdStatus {}
-
-    /**
-     * Sets the system's default NFC subscription id.
-     *
-     * <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this sets the
-     * default UICC NFCEE that will handle NFC offhost CE transactions </p>
-     *
-     * @param subscriptionId the default NFC subscription Id to set. User can get subscription id
-     *                       from {@link SubscriptionManager#getSubscriptionId(int)}
-     * @return status of the operation.
-     *
-     * @throws UnsupportedOperationException If the device does not have
-     * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
-     * @hide
-     */
-    @SystemApi
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
-    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public @SetSubscriptionIdStatus int setDefaultNfcSubscriptionId(int subscriptionId) {
-        return callServiceReturn(() ->
-                        sService.setDefaultNfcSubscriptionId(
-                                subscriptionId, mContext.getPackageName()),
-                SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR);
-    }
-
-    /**
-     * Returns the system's default NFC subscription id.
-     *
-     * <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this returns the
-     * default UICC NFCEE that will handle NFC offhost CE transactions </p>
-     * <p> If the device has no UICC that can serve as NFCEE, this will return
-     * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.</p>
-     *
-     * @return the default NFC subscription Id if set,
-     * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} otherwise.
-     *
-     * @throws UnsupportedOperationException If the device does not have
-     * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
-     */
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
-    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
-    public int getDefaultNfcSubscriptionId() {
-        return callServiceReturn(() ->
-                sService.getDefaultNfcSubscriptionId(mContext.getPackageName()),
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-    }
-
-    /**
-     * Returns the value of {@link Settings.Secure#NFC_PAYMENT_DEFAULT_COMPONENT}.
-     *
-     * @param context A context
-     * @return A ComponentName for the setting value, or null.
-     *
-     * @hide
-     */
-    @SystemApi
-    @UserHandleAware
-    @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
-    @SuppressWarnings("AndroidFrameworkClientSidePermissionCheck")
-    @FlaggedApi(android.permission.flags.Flags.FLAG_WALLET_ROLE_ENABLED)
-    @Nullable
-    public static ComponentName getPreferredPaymentService(@NonNull Context context) {
-        context.checkCallingOrSelfPermission(Manifest.permission.NFC_PREFERRED_PAYMENT_INFO);
-        String defaultPaymentComponent = Settings.Secure.getString(context.getContentResolver(),
-                Constants.SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT);
-
-        if (defaultPaymentComponent == null) {
-            return null;
-        }
-
-        return ComponentName.unflattenFromString(defaultPaymentComponent);
-    }
-
-    /** @hide */
-    interface ServiceCall {
-        void call() throws RemoteException;
-    }
-    /** @hide */
-    public static void callService(ServiceCall call) {
-        try {
-            if (sService == null) {
-                NfcAdapter.attemptDeadServiceRecovery(
-                    new RemoteException("NFC CardEmulation Service is null"));
-                sService = NfcAdapter.getCardEmulationService();
-            }
-            call.call();
-        } catch (RemoteException e) {
-            NfcAdapter.attemptDeadServiceRecovery(e);
-            sService = NfcAdapter.getCardEmulationService();
-            try {
-                call.call();
-            } catch (RemoteException ee) {
-                ee.rethrowAsRuntimeException();
-            }
-        }
-    }
-    /** @hide */
-    interface ServiceCallReturn<T> {
-        T call() throws RemoteException;
-    }
-    /** @hide */
-    public static <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) {
-        try {
-            if (sService == null) {
-                NfcAdapter.attemptDeadServiceRecovery(
-                    new RemoteException("NFC CardEmulation Service is null"));
-                sService = NfcAdapter.getCardEmulationService();
-            }
-            return call.call();
-        } catch (RemoteException e) {
-            NfcAdapter.attemptDeadServiceRecovery(e);
-            sService = NfcAdapter.getCardEmulationService();
-            // Try one more time
-            try {
-                return call.call();
-            } catch (RemoteException ee) {
-                ee.rethrowAsRuntimeException();
-            }
-        }
-        return defaultReturn;
-    }
-
-    /** @hide */
-    public static String routeIntToString(@ProtocolAndTechnologyRoute int route) {
-        return switch (route) {
-            case PROTOCOL_AND_TECHNOLOGY_ROUTE_DH -> "DH";
-            case PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE -> "eSE";
-            case PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC -> "SIM";
-            case PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET -> null;
-            case PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT -> "default";
-            default -> throw new IllegalStateException("Unexpected value: " + route);
-        };
-    }
-
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-    public static final int NFC_INTERNAL_ERROR_UNKNOWN = 0;
-
-    /**
-     * This error is reported when the NFC command watchdog restarts the NFC stack.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-    public static final int NFC_INTERNAL_ERROR_NFC_CRASH_RESTART = 1;
-
-    /**
-     * This error is reported when the NFC controller does not respond or there's an NCI transport
-     * error.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-    public static final int NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR = 2;
-
-    /**
-     * This error is reported when the NFC stack times out while waiting for a response to a command
-     * sent to the NFC hardware.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-    public static final int NFC_INTERNAL_ERROR_COMMAND_TIMEOUT = 3;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-    @IntDef(prefix = "NFC_INTERNAL_ERROR_", value = {
-            NFC_INTERNAL_ERROR_UNKNOWN,
-            NFC_INTERNAL_ERROR_NFC_CRASH_RESTART,
-            NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR,
-            NFC_INTERNAL_ERROR_COMMAND_TIMEOUT,
-    })
-    public @interface NfcInternalErrorType {}
-
-    /** Listener for preferred service state changes. */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-    public interface NfcEventCallback {
-        /**
-         * This method is called when this package gains or loses preferred Nfc service status,
-         * either the Default Wallet Role holder (see {@link
-         * android.app.role.RoleManager#ROLE_WALLET}) or the preferred service of the foreground
-         * activity set with {@link #setPreferredService(Activity, ComponentName)}
-         *
-         * @param isPreferred true is this service has become the preferred Nfc service, false if it
-         *     is no longer the preferred service
-         */
-        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-        default void onPreferredServiceChanged(boolean isPreferred) {}
-
-        /**
-         * This method is called when observe mode has been enabled or disabled.
-         *
-         * @param isEnabled true if observe mode has been enabled, false if it has been disabled
-         */
-        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-        default void onObserveModeStateChanged(boolean isEnabled) {}
-
-        /**
-         * This method is called when an AID conflict is detected during an NFC transaction. This
-         * can happen when multiple services are registered for the same AID. If your service is
-         * registered for this AID you may want to instruct users to bring your app to the
-         * foreground and ensure you call {@link #setPreferredService(Activity, ComponentName)}
-         * to ensure the transaction is routed to your service.
-         *
-         * @param aid The AID that is in conflict
-         */
-        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-        default void onAidConflictOccurred(@NonNull String aid) {}
-
-        /**
-         * This method is called when an AID is not routed to any service during an NFC
-         * transaction. This can happen when no service is registered for the given AID.
-         *
-         * @param aid the AID that was not routed
-         */
-        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-        default void onAidNotRouted(@NonNull String aid) {}
-
-        /**
-         * This method is called when the NFC state changes.
-         *
-         * @see NfcAdapter#getAdapterState()
-         *
-         * @param state The new NFC state
-         */
-        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-        default void onNfcStateChanged(@NfcAdapter.AdapterState int state) {}
-        /**
-         * This method is called when the NFC controller is in card emulation mode and an NFC
-         * reader's field is either detected or lost.
-         *
-         * @param isDetected true if an NFC reader is detected, false if it is lost
-         */
-        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-        default void onRemoteFieldChanged(boolean isDetected) {}
-
-        /**
-         * This method is called when an internal error is reported by the NFC stack.
-         *
-         * No action is required in response to these events as the NFC stack will automatically
-         * attempt to recover. These errors are reported for informational purposes only.
-         *
-         * Note that these errors can be reported when performing various internal NFC operations
-         * (such as during device shutdown) and cannot always be explicitly correlated with NFC
-         * transaction failures.
-         *
-         * @param errorType The type of the internal error
-         */
-        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-        default void onInternalErrorReported(@NfcInternalErrorType int errorType) {}
-    }
-
-    private final ArrayMap<NfcEventCallback, Executor> mNfcEventCallbacks = new ArrayMap<>();
-
-    final INfcEventCallback mINfcEventCallback =
-            new INfcEventCallback.Stub() {
-                public void onPreferredServiceChanged(ComponentNameAndUser componentNameAndUser) {
-                    if (!android.nfc.Flags.nfcEventListener()) {
-                        return;
-                    }
-                    boolean isPreferred =
-                            componentNameAndUser != null
-                                    && componentNameAndUser.getUserId()
-                                            == mContext.getUser().getIdentifier()
-                                    && componentNameAndUser.getComponentName() != null
-                                    && Objects.equals(
-                                            mContext.getPackageName(),
-                                            componentNameAndUser.getComponentName()
-                                                    .getPackageName());
-                    callListeners(listener -> listener.onPreferredServiceChanged(isPreferred));
-                }
-
-                public void onObserveModeStateChanged(boolean isEnabled) {
-                    if (!android.nfc.Flags.nfcEventListener()) {
-                        return;
-                    }
-                    callListeners(listener -> listener.onObserveModeStateChanged(isEnabled));
-                }
-
-                public void onAidConflictOccurred(String aid) {
-                    if (!android.nfc.Flags.nfcEventListener()) {
-                        return;
-                    }
-                    callListeners(listener -> listener.onAidConflictOccurred(aid));
-                }
-
-                public void onAidNotRouted(String aid) {
-                    if (!android.nfc.Flags.nfcEventListener()) {
-                        return;
-                    }
-                    callListeners(listener -> listener.onAidNotRouted(aid));
-                }
-
-                public void onNfcStateChanged(int state) {
-                    if (!android.nfc.Flags.nfcEventListener()) {
-                        return;
-                    }
-                    callListeners(listener -> listener.onNfcStateChanged(state));
-                }
-
-                public void onRemoteFieldChanged(boolean isDetected) {
-                    if (!android.nfc.Flags.nfcEventListener()) {
-                        return;
-                    }
-                    callListeners(listener -> listener.onRemoteFieldChanged(isDetected));
-                }
-
-                public void onInternalErrorReported(@NfcInternalErrorType int errorType) {
-                    if (!android.nfc.Flags.nfcEventListener()) {
-                        return;
-                    }
-                    callListeners(listener -> listener.onInternalErrorReported(errorType));
-                }
-
-                interface ListenerCall {
-                    void invoke(NfcEventCallback listener);
-                }
-
-                private void callListeners(ListenerCall listenerCall) {
-                    synchronized (mNfcEventCallbacks) {
-                        mNfcEventCallbacks.forEach(
-                            (listener, executor) -> {
-                                executor.execute(() -> listenerCall.invoke(listener));
-                            });
-                    }
-                }
-            };
-
-    /**
-     * Register a listener for NFC Events.
-     *
-     * @param executor The Executor to run the call back with
-     * @param listener The listener to register
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-    public void registerNfcEventCallback(
-            @NonNull @CallbackExecutor Executor executor, @NonNull NfcEventCallback listener) {
-        if (!android.nfc.Flags.nfcEventListener()) {
-            return;
-        }
-        synchronized (mNfcEventCallbacks) {
-            mNfcEventCallbacks.put(listener, executor);
-            if (mNfcEventCallbacks.size() == 1) {
-                callService(() -> sService.registerNfcEventCallback(mINfcEventCallback));
-            }
-        }
-    }
-
-    /**
-     * Unregister a preferred service listener that was previously registered with {@link
-     * #registerNfcEventCallback(Executor, NfcEventCallback)}
-     *
-     * @param listener The previously registered listener to unregister
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-    public void unregisterNfcEventCallback(@NonNull NfcEventCallback listener) {
-        if (!android.nfc.Flags.nfcEventListener()) {
-            return;
-        }
-        synchronized (mNfcEventCallbacks) {
-            mNfcEventCallbacks.remove(listener);
-            if (mNfcEventCallbacks.size() == 0) {
-                callService(() -> sService.unregisterNfcEventCallback(mINfcEventCallback));
-            }
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/cardemulation/HostApduService.java b/nfc/java/android/nfc/cardemulation/HostApduService.java
deleted file mode 100644
index fbf2203..0000000
--- a/nfc/java/android/nfc/cardemulation/HostApduService.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.nfc.NfcAdapter;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * <p>HostApduService is a convenience {@link Service} class that can be
- * extended to emulate an NFC card inside an Android
- * service component.
- *
- * <div class="special reference">
- * <h3>Developer Guide</h3>
- * For a general introduction to card emulation, see
- * <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
- * Host-based Card Emulation</a>.</p>
- * </div>
- *
- * <h3>NFC Protocols</h3>
- * <p>Cards emulated by this class are based on the NFC-Forum ISO-DEP
- * protocol (based on ISO/IEC 14443-4) and support processing
- * command Application Protocol Data Units (APDUs) as
- * defined in the ISO/IEC 7816-4 specification.
- *
- * <h3>Service selection</h3>
- * <p>When a remote NFC device wants to talk to your
- * service, it sends a so-called
- * "SELECT AID" APDU as defined in the ISO/IEC 7816-4 specification.
- * The AID is an application identifier defined in ISO/IEC 7816-4.
- *
- * <p>The registration procedure for AIDs is defined in the
- * ISO/IEC 7816-5 specification. If you don't want to register an
- * AID, you are free to use AIDs in the proprietary range:
- * bits 8-5 of the first byte must each be set to '1'. For example,
- * "0xF00102030405" is a proprietary AID. If you do use proprietary
- * AIDs, it is recommended to choose an AID of at least 6 bytes,
- * to reduce the risk of collisions with other applications that
- * might be using proprietary AIDs as well.
- *
- * <h3>AID groups</h3>
- * <p>In some cases, a service may need to register multiple AIDs
- * to implement a certain application, and it needs to be sure
- * that it is the default handler for all of these AIDs (as opposed
- * to some AIDs in the group going to another service).
- *
- * <p>An AID group is a list of AIDs that should be considered as
- * belonging together by the OS. For all AIDs in an AID group, the
- * OS will guarantee one of the following:
- * <ul>
- * <li>All AIDs in the group are routed to this service
- * <li>No AIDs in the group are routed to this service
- * </ul>
- * In other words, there is no in-between state, where some AIDs
- * in the group can be routed to this service, and some to another.
- * <h3>AID groups and categories</h3>
- * <p>Each AID group can be associated with a category. This allows
- * the Android OS to classify services, and it allows the user to
- * set defaults at the category level instead of the AID level.
- *
- * <p>You can use
- * {@link CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String)}
- * to determine if your service is the default handler for a category.
- *
- * <p>In this version of the platform, the only known categories
- * are {@link CardEmulation#CATEGORY_PAYMENT} and {@link CardEmulation#CATEGORY_OTHER}.
- * AID groups without a category, or with a category that is not recognized
- * by the current platform version, will automatically be
- * grouped into the {@link CardEmulation#CATEGORY_OTHER} category.
- * <h3>Service AID registration</h3>
- * <p>To tell the platform which AIDs groups
- * are requested by this service, a {@link #SERVICE_META_DATA}
- * entry must be included in the declaration of the service. An
- * example of a HostApduService manifest declaration is shown below:
- * <pre> &lt;service android:name=".MyHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"&gt;
- *     &lt;intent-filter&gt;
- *         &lt;action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/&gt;
- *     &lt;/intent-filter&gt;
- *     &lt;meta-data android:name="android.nfc.cardemulation.host_apdu_service" android:resource="@xml/apduservice"/&gt;
- * &lt;/service&gt;</pre>
- *
- * This meta-data tag points to an apduservice.xml file.
- * An example of this file with a single AID group declaration is shown below:
- * <pre>
- * &lt;host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
- *           android:description="@string/servicedesc" android:requireDeviceUnlock="false"&gt;
- *       &lt;aid-group android:description="@string/aiddescription" android:category="other">
- *           &lt;aid-filter android:name="F0010203040506"/&gt;
- *           &lt;aid-filter android:name="F0394148148100"/&gt;
- *       &lt;/aid-group&gt;
- * &lt;/host-apdu-service&gt;
- * </pre>
- *
- * <p>The {@link android.R.styleable#HostApduService &lt;host-apdu-service&gt;} is required
- * to contain a
- * {@link android.R.styleable#HostApduService_description &lt;android:description&gt;}
- * attribute that contains a user-friendly description of the service that may be shown in UI.
- * The
- * {@link android.R.styleable#HostApduService_requireDeviceUnlock &lt;requireDeviceUnlock&gt;}
- * attribute can be used to specify that the device must be unlocked before this service
- * can be invoked to handle APDUs.
- * <p>The {@link android.R.styleable#HostApduService &lt;host-apdu-service&gt;} must
- * contain one or more {@link android.R.styleable#AidGroup &lt;aid-group&gt;} tags.
- * Each {@link android.R.styleable#AidGroup &lt;aid-group&gt;} must contain one or
- * more {@link android.R.styleable#AidFilter &lt;aid-filter&gt;} tags, each of which
- * contains a single AID. The AID must be specified in hexadecimal format, and contain
- * an even number of characters.
- * <h3>AID conflict resolution</h3>
- * Multiple HostApduServices may be installed on a single device, and the same AID
- * can be registered by more than one service. The Android platform resolves AID
- * conflicts depending on which category an AID belongs to. Each category may
- * have a different conflict resolution policy. For example, for some categories
- * the user may be able to select a default service in the Android settings UI.
- * For other categories, to policy may be to always ask the user which service
- * is to be invoked in case of conflict.
- *
- * To query the conflict resolution policy for a certain category, see
- * {@link CardEmulation#getSelectionModeForCategory(String)}.
- *
- * <h3>Data exchange</h3>
- * <p>Once the platform has resolved a "SELECT AID" command APDU to a specific
- * service component, the "SELECT AID" command APDU and all subsequent
- * command APDUs will be sent to that service through
- * {@link #processCommandApdu(byte[], Bundle)}, until either:
- * <ul>
- * <li>The NFC link is broken</li>
- * <li>A "SELECT AID" APDU is received which resolves to another service</li>
- * </ul>
- * These two scenarios are indicated by a call to {@link #onDeactivated(int)}.
- *
- * <p class="note">Use of this class requires the
- * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} to be present
- * on the device.
- *
- */
-public abstract class HostApduService extends Service {
-    /**
-     * The {@link Intent} action that must be declared as handled by the service.
-     */
-    @SdkConstant(SdkConstantType.SERVICE_ACTION)
-    public static final String SERVICE_INTERFACE =
-            "android.nfc.cardemulation.action.HOST_APDU_SERVICE";
-
-    /**
-     * The name of the meta-data element that contains
-     * more information about this service.
-     */
-    public static final String SERVICE_META_DATA =
-            "android.nfc.cardemulation.host_apdu_service";
-
-    /**
-     * Reason for {@link #onDeactivated(int)}.
-     * Indicates deactivation was due to the NFC link
-     * being lost.
-     */
-    public static final int DEACTIVATION_LINK_LOSS = 0;
-
-    /**
-     * Reason for {@link #onDeactivated(int)}.
-     *
-     * <p>Indicates deactivation was due to a different AID
-     * being selected (which implicitly deselects the AID
-     * currently active on the logical channel).
-     *
-     * <p>Note that this next AID may still be resolved to this
-     * service, in which case {@link #processCommandApdu(byte[], Bundle)}
-     * will be called again.
-     */
-    public static final int DEACTIVATION_DESELECTED = 1;
-
-    static final String TAG = "ApduService";
-
-    /**
-     * MSG_COMMAND_APDU is sent by NfcService when
-     * a 7816-4 command APDU has been received.
-     *
-     * @hide
-     */
-    public static final int MSG_COMMAND_APDU = 0;
-
-    /**
-     * MSG_RESPONSE_APDU is sent to NfcService to send
-     * a response APDU back to the remote device.
-     *
-     * @hide
-     */
-    public static final int MSG_RESPONSE_APDU = 1;
-
-    /**
-     * MSG_DEACTIVATED is sent by NfcService when
-     * the current session is finished; either because
-     * another AID was selected that resolved to
-     * another service, or because the NFC link
-     * was deactivated.
-     *
-     * @hide
-     */
-    public static final int MSG_DEACTIVATED = 2;
-
-    /**
-     *
-     * @hide
-     */
-    public static final int MSG_UNHANDLED = 3;
-
-    /**
-     * @hide
-     */
-    public static final int MSG_POLLING_LOOP = 4;
-
-
-    /**
-     * @hide
-     */
-    public static final String KEY_DATA = "data";
-
-    /**
-     * @hide
-     */
-    public static final String KEY_POLLING_LOOP_FRAMES_BUNDLE =
-            "android.nfc.cardemulation.POLLING_FRAMES";
-
-    /**
-     * Messenger interface to NfcService for sending responses.
-     * Only accessed on main thread by the message handler.
-     *
-     * @hide
-     */
-    Messenger mNfcService = null;
-
-    final Messenger mMessenger = new Messenger(new MsgHandler());
-
-    final class MsgHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-            case MSG_COMMAND_APDU:
-                Bundle dataBundle = msg.getData();
-                if (dataBundle == null) {
-                    return;
-                }
-                if (mNfcService == null) mNfcService = msg.replyTo;
-
-                byte[] apdu = dataBundle.getByteArray(KEY_DATA);
-                if (apdu != null) {
-                        HostApduService has = HostApduService.this;
-                    byte[] responseApdu = processCommandApdu(apdu, null);
-                    if (responseApdu != null) {
-                        if (mNfcService == null) {
-                            Log.e(TAG, "Response not sent; service was deactivated.");
-                            return;
-                        }
-                        Message responseMsg = Message.obtain(null, MSG_RESPONSE_APDU);
-                        Bundle responseBundle = new Bundle();
-                        responseBundle.putByteArray(KEY_DATA, responseApdu);
-                        responseMsg.setData(responseBundle);
-                        responseMsg.replyTo = mMessenger;
-                        try {
-                            mNfcService.send(responseMsg);
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "Response not sent; RemoteException calling into " +
-                                    "NfcService.");
-                        }
-                    }
-                } else {
-                    Log.e(TAG, "Received MSG_COMMAND_APDU without data.");
-                }
-                break;
-            case MSG_RESPONSE_APDU:
-                if (mNfcService == null) {
-                    Log.e(TAG, "Response not sent; service was deactivated.");
-                    return;
-                }
-                try {
-                    msg.replyTo = mMessenger;
-                    mNfcService.send(msg);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "RemoteException calling into NfcService.");
-                }
-                break;
-            case MSG_DEACTIVATED:
-                // Make sure we won't call into NfcService again
-                mNfcService = null;
-                onDeactivated(msg.arg1);
-                break;
-            case MSG_UNHANDLED:
-                if (mNfcService == null) {
-                    Log.e(TAG, "notifyUnhandled not sent; service was deactivated.");
-                    return;
-                }
-                try {
-                    msg.replyTo = mMessenger;
-                    mNfcService.send(msg);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "RemoteException calling into NfcService.");
-                }
-                break;
-                case MSG_POLLING_LOOP:
-                    if (android.nfc.Flags.nfcReadPollingLoop()) {
-                        ArrayList<PollingFrame> pollingFrames =
-                                msg.getData().getParcelableArrayList(
-                                    KEY_POLLING_LOOP_FRAMES_BUNDLE, PollingFrame.class);
-                        processPollingFrames(pollingFrames);
-                    }
-                    break;
-                default:
-                super.handleMessage(msg);
-            }
-        }
-    }
-
-    @Override
-    public final IBinder onBind(Intent intent) {
-        return mMessenger.getBinder();
-    }
-
-    /**
-     * Sends a response APDU back to the remote device.
-     *
-     * <p>Note: this method may be called from any thread and will not block.
-     * @param responseApdu A byte-array containing the reponse APDU.
-     */
-    public final void sendResponseApdu(byte[] responseApdu) {
-        Message responseMsg = Message.obtain(null, MSG_RESPONSE_APDU);
-        Bundle dataBundle = new Bundle();
-        dataBundle.putByteArray(KEY_DATA, responseApdu);
-        responseMsg.setData(dataBundle);
-        try {
-            mMessenger.send(responseMsg);
-        } catch (RemoteException e) {
-            Log.e("TAG", "Local messenger has died.");
-        }
-    }
-
-    /**
-     * Calling this method allows the service to tell the OS
-     * that it won't be able to complete this transaction -
-     * for example, because it requires data connectivity
-     * that is not present at that moment.
-     *
-     * The OS may use this indication to give the user a list
-     * of alternative applications that can handle the last
-     * AID that was selected. If the user would select an
-     * application from the list, that action by itself
-     * will not cause the default to be changed; the selected
-     * application will be invoked for the next tap only.
-     *
-     * If there are no other applications that can handle
-     * this transaction, the OS will show an error dialog
-     * indicating your service could not complete the
-     * transaction.
-     *
-     * <p>Note: this method may be called anywhere between
-     *    the first {@link #processCommandApdu(byte[], Bundle)}
-     *    call and a {@link #onDeactivated(int)} call.
-     */
-    public final void notifyUnhandled() {
-        Message unhandledMsg = Message.obtain(null, MSG_UNHANDLED);
-        try {
-            mMessenger.send(unhandledMsg);
-        } catch (RemoteException e) {
-            Log.e("TAG", "Local messenger has died.");
-        }
-    }
-
-    /**
-     * This method is called when polling frames have been received from a
-     * remote device. If the device is in observe mode, the service should
-     * call {@link NfcAdapter#allowTransaction()} once it is ready to proceed
-     * with the transaction. If the device is not in observe mode, the service
-     * can use this polling frame information to determine how to proceed if it
-     * subsequently has {@link #processCommandApdu(byte[], Bundle)} called. The
-     * service must override this method inorder to receive polling frames,
-     * otherwise the base implementation drops the frame.
-     *
-     * @param frame A description of the polling frame.
-     */
-    @SuppressLint("OnNameExpected")
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public void processPollingFrames(@NonNull List<PollingFrame> frame) {
-    }
-
-    /**
-     * <p>This method will be called when a command APDU has been received
-     * from a remote device. A response APDU can be provided directly
-     * by returning a byte-array in this method. Note that in general
-     * response APDUs must be sent as quickly as possible, given the fact
-     * that the user is likely holding their device over an NFC reader
-     * when this method is called.
-     *
-     * <p class="note">If there are multiple services that have registered for the same
-     * AIDs in their meta-data entry, you will only get called if the user has
-     * explicitly selected your service, either as a default or just for the next tap.
-     *
-     * <p class="note">This method is running on the main thread of your application.
-     * If you cannot return a response APDU immediately, return null
-     * and use the {@link #sendResponseApdu(byte[])} method later.
-     *
-     * @param commandApdu The APDU that was received from the remote device
-     * @param extras A bundle containing extra data. May be null.
-     * @return a byte-array containing the response APDU, or null if no
-     *         response APDU can be sent at this point.
-     */
-    public abstract byte[] processCommandApdu(byte[] commandApdu, Bundle extras);
-
-    /**
-     * This method will be called in two possible scenarios:
-     * <li>The NFC link has been deactivated or lost
-     * <li>A different AID has been selected and was resolved to a different
-     *     service component
-     * @param reason Either {@link #DEACTIVATION_LINK_LOSS} or {@link #DEACTIVATION_DESELECTED}
-     */
-    public abstract void onDeactivated(int reason);
-
-}
diff --git a/nfc/java/android/nfc/cardemulation/HostNfcFService.java b/nfc/java/android/nfc/cardemulation/HostNfcFService.java
deleted file mode 100644
index 65b5ca7..0000000
--- a/nfc/java/android/nfc/cardemulation/HostNfcFService.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * <p>HostNfcFService is a convenience {@link Service} class that can be
- * extended to emulate an NFC-F card inside an Android service component.
- *
- * <h3>NFC Protocols</h3>
- * <p>Cards emulated by this class are based on the NFC-Forum NFC-F
- * protocol (based on the JIS-X 6319-4 specification.)</p>
- *
- * <h3>System Code and NFCID2 registration</h3>
- * <p>A {@link HostNfcFService HostNfcFService service} can register
- * exactly one System Code and one NFCID2. For details about the use of
- * System Code and NFCID2, see the NFC Forum Digital specification.</p>
- * <p>To statically register a System Code and NFCID2 with the service, a {@link #SERVICE_META_DATA}
- * entry must be included in the declaration of the service.
- *
- * <p>All {@link HostNfcFService HostNfcFService} declarations in the manifest must require the
- * {@link android.Manifest.permission#BIND_NFC_SERVICE} permission
- * in their &lt;service&gt; tag, to ensure that only the platform can bind to your service.</p>
- *
- * <p>An example of a HostNfcFService manifest declaration is shown below:
- *
- * <pre> &lt;service android:name=".MyHostNfcFService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"&gt;
- *     &lt;intent-filter&gt;
- *         &lt;action android:name="android.nfc.cardemulation.action.HOST_NFCF_SERVICE"/&gt;
- *     &lt;/intent-filter&gt;
- *     &lt;meta-data android:name="android.nfc.cardemulation.host_nfcf_service" android:resource="@xml/nfcfservice"/&gt;
- * &lt;/service&gt;</pre>
- *
- * This meta-data tag points to an nfcfservice.xml file.
- * An example of this file with a System Code and NFCID2 declaration is shown below:
- * <pre>
- * &lt;host-nfcf-service xmlns:android="http://schemas.android.com/apk/res/android"
- *           android:description="@string/servicedesc"&gt;
- *       &lt;system-code-filter android:name="4000"/&gt;
- *       &lt;nfcid2-filter android:name="02FE000000000000"/&gt;
-         &lt;t3tPmm-filter android:name="FFFFFFFFFFFFFFFF"/&gt;
- * &lt;/host-nfcf-service&gt;
- * </pre>
- *
- * <p>The {@link android.R.styleable#HostNfcFService &lt;host-nfcf-service&gt;} is required
- * to contain a
- * {@link android.R.styleable#HostApduService_description &lt;android:description&gt;}
- * attribute that contains a user-friendly description of the service that may be shown in UI.
- * <p>The {@link android.R.styleable#HostNfcFService &lt;host-nfcf-service&gt;} must
- * contain:
- * <ul>
- * <li>Exactly one {@link android.R.styleable#SystemCodeFilter &lt;system-code-filter&gt;} tag.</li>
- * <li>Exactly one {@link android.R.styleable#Nfcid2Filter &lt;nfcid2-filter&gt;} tag.</li>
- * <li>Zero or one {@link android.R.styleable#T3tPmmFilter &lt;t3tPmm-filter&gt;} tag.</li>
- * </ul>
- * </p>
- *
- * <p>Alternatively, the System Code and NFCID2 can be dynamically registererd for a service
- * by using the {@link NfcFCardEmulation#registerSystemCodeForService(ComponentName, String)} and
- * {@link NfcFCardEmulation#setNfcid2ForService(ComponentName, String)} methods.
- * </p>
- *
- * <h3>Service selection</h3>
- * <p>When a remote NFC devices wants to communicate with your service, it
- * sends a SENSF_REQ command to the NFC controller, requesting a System Code.
- * If a {@link NfcFCardEmulation NfcFCardEmulation service} has registered
- * this system code and has been enabled by the foreground application, the
- * NFC controller will respond with the NFCID2 that is registered for this service.
- * The reader can then continue data exchange with this service by using the NFCID2.</p>
- *
- * <h3>Data exchange</h3>
- * <p>After service selection, all frames addressed to the NFCID2 of this service will
- * be sent through {@link #processNfcFPacket(byte[], Bundle)}, until the NFC link is
- * broken.<p>
- *
- * <p>When the NFC link is broken, {@link #onDeactivated(int)} will be called.</p>
- */
-public abstract class HostNfcFService extends Service {
-    /**
-     * The {@link Intent} action that must be declared as handled by the service.
-     */
-    @SdkConstant(SdkConstantType.SERVICE_ACTION)
-    public static final String SERVICE_INTERFACE =
-            "android.nfc.cardemulation.action.HOST_NFCF_SERVICE";
-
-    /**
-     * The name of the meta-data element that contains
-     * more information about this service.
-     */
-    public static final String SERVICE_META_DATA =
-            "android.nfc.cardemulation.host_nfcf_service";
-
-    /**
-     * Reason for {@link #onDeactivated(int)}.
-     * Indicates deactivation was due to the NFC link
-     * being lost.
-     */
-    public static final int DEACTIVATION_LINK_LOSS = 0;
-
-    static final String TAG = "NfcFService";
-
-    /**
-     * MSG_COMMAND_PACKET is sent by NfcService when
-     * a NFC-F command packet has been received.
-     *
-     * @hide
-     */
-    public static final int MSG_COMMAND_PACKET = 0;
-
-    /**
-     * MSG_RESPONSE_PACKET is sent to NfcService to send
-     * a response packet back to the remote device.
-     *
-     * @hide
-     */
-    public static final int MSG_RESPONSE_PACKET = 1;
-
-    /**
-     * MSG_DEACTIVATED is sent by NfcService when
-     * the current session is finished; because
-     * the NFC link was deactivated.
-     *
-     * @hide
-     */
-    public static final int MSG_DEACTIVATED = 2;
-
-   /**
-     * @hide
-     */
-    public static final String KEY_DATA = "data";
-
-    /**
-     * @hide
-     */
-    public static final String KEY_MESSENGER = "messenger";
-
-    /**
-     * Messenger interface to NfcService for sending responses.
-     * Only accessed on main thread by the message handler.
-     *
-     * @hide
-     */
-    Messenger mNfcService = null;
-
-    final Messenger mMessenger = new Messenger(new MsgHandler());
-
-    final class MsgHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-            case MSG_COMMAND_PACKET:
-                Bundle dataBundle = msg.getData();
-                if (dataBundle == null) {
-                    return;
-                }
-                if (mNfcService == null) mNfcService = msg.replyTo;
-
-                byte[] packet = dataBundle.getByteArray(KEY_DATA);
-                if (packet != null) {
-                    byte[] responsePacket = processNfcFPacket(packet, null);
-                    if (responsePacket != null) {
-                        if (mNfcService == null) {
-                            Log.e(TAG, "Response not sent; service was deactivated.");
-                            return;
-                        }
-                        Message responseMsg = Message.obtain(null, MSG_RESPONSE_PACKET);
-                        Bundle responseBundle = new Bundle();
-                        responseBundle.putByteArray(KEY_DATA, responsePacket);
-                        responseMsg.setData(responseBundle);
-                        responseMsg.replyTo = mMessenger;
-                        try {
-                            mNfcService.send(responseMsg);
-                        } catch (RemoteException e) {
-                            Log.e("TAG", "Response not sent; RemoteException calling into " +
-                                    "NfcService.");
-                        }
-                    }
-                } else {
-                    Log.e(TAG, "Received MSG_COMMAND_PACKET without data.");
-                }
-                break;
-            case MSG_RESPONSE_PACKET:
-                if (mNfcService == null) {
-                    Log.e(TAG, "Response not sent; service was deactivated.");
-                    return;
-                }
-                try {
-                    msg.replyTo = mMessenger;
-                    mNfcService.send(msg);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "RemoteException calling into NfcService.");
-                }
-                break;
-            case MSG_DEACTIVATED:
-                // Make sure we won't call into NfcService again
-                mNfcService = null;
-                onDeactivated(msg.arg1);
-                break;
-            default:
-                super.handleMessage(msg);
-            }
-        }
-    }
-
-    @Override
-    public final IBinder onBind(Intent intent) {
-        return mMessenger.getBinder();
-    }
-
-    /**
-     * Sends a response packet back to the remote device.
-     *
-     * <p>Note: this method may be called from any thread and will not block.
-     * @param responsePacket A byte-array containing the response packet.
-     */
-    public final void sendResponsePacket(byte[] responsePacket) {
-        Message responseMsg = Message.obtain(null, MSG_RESPONSE_PACKET);
-        Bundle dataBundle = new Bundle();
-        dataBundle.putByteArray(KEY_DATA, responsePacket);
-        responseMsg.setData(dataBundle);
-        try {
-            mMessenger.send(responseMsg);
-        } catch (RemoteException e) {
-            Log.e("TAG", "Local messenger has died.");
-        }
-    }
-
-    /**
-     * <p>This method will be called when a NFC-F packet has been received
-     * from a remote device. A response packet can be provided directly
-     * by returning a byte-array in this method. Note that in general
-     * response packets must be sent as quickly as possible, given the fact
-     * that the user is likely holding their device over an NFC reader
-     * when this method is called.
-     *
-     * <p class="note">This method is running on the main thread of your application.
-     * If you cannot return a response packet immediately, return null
-     * and use the {@link #sendResponsePacket(byte[])} method later.
-     *
-     * @param commandPacket The NFC-F packet that was received from the remote device
-     * @param extras A bundle containing extra data. May be null.
-     * @return a byte-array containing the response packet, or null if no
-     *         response packet can be sent at this point.
-     */
-    public abstract byte[] processNfcFPacket(byte[] commandPacket, Bundle extras);
-
-    /**
-     * This method will be called in following possible scenarios:
-     * <li>The NFC link has been lost
-     * @param reason {@link #DEACTIVATION_LINK_LOSS}
-     */
-    public abstract void onDeactivated(int reason);
-}
diff --git a/nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java b/nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java
deleted file mode 100644
index 48bbf5b6..0000000
--- a/nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.nfc.INfcFCardEmulation;
-import android.nfc.NfcAdapter;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * This class can be used to query the state of
- * NFC-F card emulation services.
- *
- * For a general introduction into NFC card emulation,
- * please read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
- * NFC card emulation developer guide</a>.</p>
- *
- * <p class="note">Use of this class requires the
- * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION_NFCF}
- * to be present on the device.
- */
-public final class NfcFCardEmulation {
-    static final String TAG = "NfcFCardEmulation";
-
-    static boolean sIsInitialized = false;
-    static HashMap<Context, NfcFCardEmulation> sCardEmus = new HashMap<Context, NfcFCardEmulation>();
-    static INfcFCardEmulation sService;
-
-    final Context mContext;
-
-    private NfcFCardEmulation(Context context, INfcFCardEmulation service) {
-        mContext = context.getApplicationContext();
-        sService = service;
-    }
-
-    /**
-     * Helper to get an instance of this class.
-     *
-     * @param adapter A reference to an NfcAdapter object.
-     * @return
-     */
-    public static synchronized NfcFCardEmulation getInstance(NfcAdapter adapter) {
-        if (adapter == null) throw new NullPointerException("NfcAdapter is null");
-        Context context = adapter.getContext();
-        if (context == null) {
-            Log.e(TAG, "NfcAdapter context is null.");
-            throw new UnsupportedOperationException();
-        }
-        if (!sIsInitialized) {
-            PackageManager pm = context.getPackageManager();
-            if (pm == null) {
-                Log.e(TAG, "Cannot get PackageManager");
-                throw new UnsupportedOperationException();
-            }
-            if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)) {
-                Log.e(TAG, "This device does not support NFC-F card emulation");
-                throw new UnsupportedOperationException();
-            }
-            sIsInitialized = true;
-        }
-        NfcFCardEmulation manager = sCardEmus.get(context);
-        if (manager == null) {
-            // Get card emu service
-            INfcFCardEmulation service = adapter.getNfcFCardEmulationService();
-            if (service == null) {
-                Log.e(TAG, "This device does not implement the INfcFCardEmulation interface.");
-                throw new UnsupportedOperationException();
-            }
-            manager = new NfcFCardEmulation(context, service);
-            sCardEmus.put(context, manager);
-        }
-        return manager;
-    }
-
-    /**
-     * Retrieves the current System Code for the specified service.
-     *
-     * <p>Before calling {@link #registerSystemCodeForService(ComponentName, String)},
-     * the System Code contained in the Manifest file is returned. After calling
-     * {@link #registerSystemCodeForService(ComponentName, String)}, the System Code
-     * registered there is returned. After calling
-     * {@link #unregisterSystemCodeForService(ComponentName)}, "null" is returned.
-     *
-     * @param service The component name of the service
-     * @return the current System Code
-     */
-    public String getSystemCodeForService(ComponentName service) throws RuntimeException {
-        if (service == null) {
-            throw new NullPointerException("service is null");
-        }
-        try {
-            return sService.getSystemCodeForService(mContext.getUser().getIdentifier(), service);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
-            }
-            try {
-                return sService.getSystemCodeForService(mContext.getUser().getIdentifier(),
-                        service);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return null;
-            }
-        }
-    }
-
-    /**
-     * Registers a System Code for the specified service.
-     *
-     * <p>The System Code must be in range from "4000" to "4FFF" (excluding "4*FF").
-     *
-     * <p>If a System Code was previously registered for this service
-     * (either statically through the manifest, or dynamically by using this API),
-     * it will be replaced with this one.
-     *
-     * <p>Even if the same System Code is already registered for another service,
-     * this method succeeds in registering the System Code.
-     *
-     * <p>Note that you can only register a System Code for a service that
-     * is running under the same UID as the caller of this API. Typically
-     * this means you need to call this from the same
-     * package as the service itself, though UIDs can also
-     * be shared between packages using shared UIDs.
-     *
-     * @param service The component name of the service
-     * @param systemCode The System Code to be registered
-     * @return whether the registration was successful.
-     */
-    public boolean registerSystemCodeForService(ComponentName service, String systemCode)
-            throws RuntimeException {
-        if (service == null || systemCode == null) {
-            throw new NullPointerException("service or systemCode is null");
-        }
-        try {
-            return sService.registerSystemCodeForService(mContext.getUser().getIdentifier(),
-                    service, systemCode);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.registerSystemCodeForService(mContext.getUser().getIdentifier(),
-                        service, systemCode);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Removes a registered System Code for the specified service.
-     *
-     * @param service The component name of the service
-     * @return whether the System Code was successfully removed.
-     */
-    public boolean unregisterSystemCodeForService(ComponentName service) throws RuntimeException {
-        if (service == null) {
-            throw new NullPointerException("service is null");
-        }
-        try {
-            return sService.removeSystemCodeForService(mContext.getUser().getIdentifier(), service);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.removeSystemCodeForService(mContext.getUser().getIdentifier(),
-                        service);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Retrieves the current NFCID2 for the specified service.
-     *
-     * <p>Before calling {@link #setNfcid2ForService(ComponentName, String)},
-     * the NFCID2 contained in the Manifest file is returned. If "random" is specified
-     * in the Manifest file, a random number assigned by the system at installation time
-     * is returned. After setting an NFCID2
-     * with {@link #setNfcid2ForService(ComponentName, String)}, this NFCID2 is returned.
-     *
-     * @param service The component name of the service
-     * @return the current NFCID2
-     */
-    public String getNfcid2ForService(ComponentName service) throws RuntimeException {
-        if (service == null) {
-            throw new NullPointerException("service is null");
-        }
-        try {
-            return sService.getNfcid2ForService(mContext.getUser().getIdentifier(), service);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
-            }
-            try {
-                return sService.getNfcid2ForService(mContext.getUser().getIdentifier(), service);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return null;
-            }
-        }
-    }
-
-    /**
-     * Set a NFCID2 for the specified service.
-     *
-     * <p>The NFCID2 must be in range from "02FE000000000000" to "02FEFFFFFFFFFFFF".
-     *
-     * <p>If a NFCID2 was previously set for this service
-     * (either statically through the manifest, or dynamically by using this API),
-     * it will be replaced.
-     *
-     * <p>Note that you can only set the NFCID2 for a service that
-     * is running under the same UID as the caller of this API. Typically
-     * this means you need to call this from the same
-     * package as the service itself, though UIDs can also
-     * be shared between packages using shared UIDs.
-     *
-     * @param service The component name of the service
-     * @param nfcid2 The NFCID2 to be registered
-     * @return whether the setting was successful.
-     */
-    public boolean setNfcid2ForService(ComponentName service, String nfcid2)
-            throws RuntimeException {
-        if (service == null || nfcid2 == null) {
-            throw new NullPointerException("service or nfcid2 is null");
-        }
-        try {
-            return sService.setNfcid2ForService(mContext.getUser().getIdentifier(),
-                    service, nfcid2);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.setNfcid2ForService(mContext.getUser().getIdentifier(),
-                        service, nfcid2);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Allows a foreground application to specify which card emulation service
-     * should be enabled while a specific Activity is in the foreground.
-     *
-     * <p>The specified HCE-F service is only enabled when the corresponding application is
-     * in the foreground and this method has been called. When the application is moved to
-     * the background, {@link #disableService(Activity)} is called, or
-     * NFCID2 or System Code is replaced, the HCE-F service is disabled.
-     *
-     * <p>The specified Activity must currently be in resumed state. A good
-     * paradigm is to call this method in your {@link Activity#onResume}, and to call
-     * {@link #disableService(Activity)} in your {@link Activity#onPause}.
-     *
-     * <p>Note that this preference is not persisted by the OS, and hence must be
-     * called every time the Activity is resumed.
-     *
-     * @param activity The activity which prefers this service to be invoked
-     * @param service The service to be preferred while this activity is in the foreground
-     * @return whether the registration was successful
-     */
-    public boolean enableService(Activity activity, ComponentName service) throws RuntimeException {
-        if (activity == null || service == null) {
-            throw new NullPointerException("activity or service is null");
-        }
-        // Verify the activity is in the foreground before calling into NfcService
-        if (!activity.isResumed()) {
-            throw new IllegalArgumentException("Activity must be resumed.");
-        }
-        try {
-            return sService.enableNfcFForegroundService(service);
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.enableNfcFForegroundService(service);
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Disables the service for the specified Activity.
-     *
-     * <p>Note that the specified Activity must still be in resumed
-     * state at the time of this call. A good place to call this method
-     * is in your {@link Activity#onPause} implementation.
-     *
-     * @param activity The activity which the service was registered for
-     * @return true when successful
-     */
-    public boolean disableService(Activity activity) throws RuntimeException {
-        if (activity == null) {
-            throw new NullPointerException("activity is null");
-        }
-        if (!activity.isResumed()) {
-            throw new IllegalArgumentException("Activity must be resumed.");
-        }
-        try {
-            return sService.disableNfcFForegroundService();
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return false;
-            }
-            try {
-                return sService.disableNfcFForegroundService();
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                ee.rethrowAsRuntimeException();
-                return false;
-            }
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public List<NfcFServiceInfo> getNfcFServices() {
-        try {
-            return sService.getNfcFServices(mContext.getUser().getIdentifier());
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return null;
-            }
-            try {
-                return sService.getNfcFServices(mContext.getUser().getIdentifier());
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                return null;
-            }
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public int getMaxNumOfRegisterableSystemCodes() {
-        try {
-            return sService.getMaxNumOfRegisterableSystemCodes();
-        } catch (RemoteException e) {
-            // Try one more time
-            recoverService();
-            if (sService == null) {
-                Log.e(TAG, "Failed to recover CardEmulationService.");
-                return -1;
-            }
-            try {
-                return sService.getMaxNumOfRegisterableSystemCodes();
-            } catch (RemoteException ee) {
-                Log.e(TAG, "Failed to reach CardEmulationService.");
-                return -1;
-            }
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public static boolean isValidSystemCode(String systemCode) {
-        if (systemCode == null) {
-            return false;
-        }
-        if (systemCode.length() != 4) {
-            Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
-            return false;
-        }
-        // check if the value is between "4000" and "4FFF" (excluding "4*FF")
-        if (!systemCode.startsWith("4") || systemCode.toUpperCase().endsWith("FF")) {
-            Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
-            return false;
-        }
-        try {
-            Integer.parseInt(systemCode, 16);
-        } catch (NumberFormatException e) {
-            Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * @hide
-     */
-    public static boolean isValidNfcid2(String nfcid2) {
-        if (nfcid2 == null) {
-            return false;
-        }
-        if (nfcid2.length() != 16) {
-            Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
-            return false;
-        }
-        // check if the the value starts with "02FE"
-        if (!nfcid2.toUpperCase().startsWith("02FE")) {
-            Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
-            return false;
-        }
-        try {
-            Long.parseLong(nfcid2, 16);
-        } catch (NumberFormatException e) {
-            Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
-            return false;
-        }
-        return true;
-    }
-
-    void recoverService() {
-        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
-        sService = adapter.getNfcFCardEmulationService();
-    }
-
-}
-
diff --git a/nfc/java/android/nfc/cardemulation/OffHostApduService.java b/nfc/java/android/nfc/cardemulation/OffHostApduService.java
deleted file mode 100644
index 8d8a172..0000000
--- a/nfc/java/android/nfc/cardemulation/OffHostApduService.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.os.IBinder;
-
-/**
- * <p>OffHostApduService is a convenience {@link Service} class that can be
- * extended to describe one or more NFC applications that are residing
- * off-host, for example on an embedded secure element or a UICC.
- *
- * <div class="special reference">
- * <h3>Developer Guide</h3>
- * For a general introduction into the topic of card emulation,
- * please read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
- * NFC card emulation developer guide.</a></p>
- * </div>
- *
- * <h3>NFC Protocols</h3>
- * <p>Off-host applications represented by this class are based on the NFC-Forum ISO-DEP
- * protocol (based on ISO/IEC 14443-4) and support processing
- * command Application Protocol Data Units (APDUs) as
- * defined in the ISO/IEC 7816-4 specification.
- *
- * <h3>Service selection</h3>
- * <p>When a remote NFC device wants to talk to your
- * off-host NFC application, it sends a so-called
- * "SELECT AID" APDU as defined in the ISO/IEC 7816-4 specification.
- * The AID is an application identifier defined in ISO/IEC 7816-4.
- *
- * <p>The registration procedure for AIDs is defined in the
- * ISO/IEC 7816-5 specification. If you don't want to register an
- * AID, you are free to use AIDs in the proprietary range:
- * bits 8-5 of the first byte must each be set to '1'. For example,
- * "0xF00102030405" is a proprietary AID. If you do use proprietary
- * AIDs, it is recommended to choose an AID of at least 6 bytes,
- * to reduce the risk of collisions with other applications that
- * might be using proprietary AIDs as well.
- *
- * <h3>AID groups</h3>
- * <p>In some cases, an off-host environment may need to register multiple AIDs
- * to implement a certain application, and it needs to be sure
- * that it is the default handler for all of these AIDs (as opposed
- * to some AIDs in the group going to another service).
- *
- * <p>An AID group is a list of AIDs that should be considered as
- * belonging together by the OS. For all AIDs in an AID group, the
- * OS will guarantee one of the following:
- * <ul>
- * <li>All AIDs in the group are routed to the off-host execution environment
- * <li>No AIDs in the group are routed to the off-host execution environment
- * </ul>
- * In other words, there is no in-between state, where some AIDs
- * in the group can be routed to this off-host execution environment,
- * and some to another or a host-based {@link HostApduService}.
- * <h3>AID groups and categories</h3>
- * <p>Each AID group can be associated with a category. This allows
- * the Android OS to classify services, and it allows the user to
- * set defaults at the category level instead of the AID level.
- *
- * <p>You can use
- * {@link CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String)}
- * to determine if your off-host service is the default handler for a category.
- *
- * <p>In this version of the platform, the only known categories
- * are {@link CardEmulation#CATEGORY_PAYMENT} and {@link CardEmulation#CATEGORY_OTHER}.
- * AID groups without a category, or with a category that is not recognized
- * by the current platform version, will automatically be
- * grouped into the {@link CardEmulation#CATEGORY_OTHER} category.
- *
- * <h3>Service AID registration</h3>
- * <p>To tell the platform which AIDs
- * reside off-host and are managed by this service, a {@link #SERVICE_META_DATA}
- * entry must be included in the declaration of the service. An
- * example of a OffHostApduService manifest declaration is shown below:
- * <pre> &lt;service android:name=".MyOffHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"&gt;
- *     &lt;intent-filter&gt;
- *         &lt;action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/&gt;
- *     &lt;/intent-filter&gt;
- *     &lt;meta-data android:name="android.nfc.cardemulation.off_host_apdu_service" android:resource="@xml/apduservice"/&gt;
- * &lt;/service&gt;</pre>
- *
- * This meta-data tag points to an apduservice.xml file.
- * An example of this file with a single AID group declaration is shown below:
- * <pre>
- * &lt;offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
- *           android:description="@string/servicedesc"&gt;
- *       &lt;aid-group android:description="@string/subscription" android:category="other">
- *           &lt;aid-filter android:name="F0010203040506"/&gt;
- *           &lt;aid-filter android:name="F0394148148100"/&gt;
- *       &lt;/aid-group&gt;
- * &lt;/offhost-apdu-service&gt;
- * </pre>
- *
- * <p>The {@link android.R.styleable#OffHostApduService &lt;offhost-apdu-service&gt;} is required
- * to contain a
- * {@link android.R.styleable#OffHostApduService_description &lt;android:description&gt;}
- * attribute that contains a user-friendly description of the service that may be shown in UI.
- *
- * <p>The {@link android.R.styleable#OffHostApduService &lt;offhost-apdu-service&gt;} must
- * contain one or more {@link android.R.styleable#AidGroup &lt;aid-group&gt;} tags.
- * Each {@link android.R.styleable#AidGroup &lt;aid-group&gt;} must contain one or
- * more {@link android.R.styleable#AidFilter &lt;aid-filter&gt;} tags, each of which
- * contains a single AID. The AID must be specified in hexadecimal format, and contain
- * an even number of characters.
- *
- * <p>This registration will allow the service to be included
- * as an option for being the default handler for categories.
- * The Android OS will take care of correctly
- * routing the AIDs to the off-host execution environment,
- * based on which service the user has selected to be the handler for a certain category.
- *
- * <p>The service may define additional actions outside of the
- * Android namespace that provide further interaction with
- * the off-host execution environment.
- *
- * <p class="note">Use of this class requires the
- * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} to be present
- * on the device.
- */
-public abstract class OffHostApduService extends Service {
-    /**
-     * The {@link Intent} action that must be declared as handled by the service.
-     */
-    @SdkConstant(SdkConstantType.SERVICE_ACTION)
-    public static final String SERVICE_INTERFACE =
-            "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE";
-
-    /**
-     * The name of the meta-data element that contains
-     * more information about this service.
-     */
-    public static final String SERVICE_META_DATA =
-            "android.nfc.cardemulation.off_host_apdu_service";
-
-    /**
-     * The Android platform itself will not bind to this service,
-     * but merely uses its declaration to keep track of what AIDs
-     * the service is interested in. This information is then used
-     * to present the user with a list of applications that can handle
-     * an AID, as well as correctly route those AIDs either to the host (in case
-     * the user preferred a {@link HostApduService}), or to an off-host
-     * execution environment (in case the user preferred a {@link OffHostApduService}.
-     *
-     * Implementers may define additional actions outside of the
-     * Android namespace that allow further interactions with
-     * the off-host execution environment. Such implementations
-     * would need to override this method.
-     */
-    public abstract IBinder onBind(Intent intent);
-}
diff --git a/nfc/java/android/nfc/cardemulation/PollingFrame.aidl b/nfc/java/android/nfc/cardemulation/PollingFrame.aidl
deleted file mode 100644
index 8e09f8b..0000000
--- a/nfc/java/android/nfc/cardemulation/PollingFrame.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc.cardemulation;
-
-parcelable PollingFrame;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/cardemulation/PollingFrame.java b/nfc/java/android/nfc/cardemulation/PollingFrame.java
deleted file mode 100644
index 5dcc84c..0000000
--- a/nfc/java/android/nfc/cardemulation/PollingFrame.java
+++ /dev/null
@@ -1,283 +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 android.nfc.cardemulation;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.HexFormat;
-import java.util.List;
-
-/**
- * Polling Frames represent data about individual frames of an NFC polling loop. These frames will
- * be delivered to subclasses of {@link HostApduService} that have registered filters with
- * {@link CardEmulation#registerPollingLoopFilterForService(ComponentName, String, boolean)} that
- * match a given frame in a loop and will be delivered through calls to
- * {@link HostApduService#processPollingFrames(List)}.
- */
-@FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-public final class PollingFrame implements Parcelable {
-
-    /**
-     * @hide
-     */
-    @IntDef(prefix = { "POLLING_LOOP_TYPE_"},
-        value = {
-            POLLING_LOOP_TYPE_A,
-            POLLING_LOOP_TYPE_B,
-            POLLING_LOOP_TYPE_F,
-            POLLING_LOOP_TYPE_OFF,
-            POLLING_LOOP_TYPE_ON,
-            POLLING_LOOP_TYPE_UNKNOWN
-        })
-    @Retention(RetentionPolicy.SOURCE)
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public @interface PollingFrameType {}
-
-    /**
-     * POLLING_LOOP_TYPE_A is the value associated with the key
-     * POLLING_LOOP_TYPE  in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
-     * when the polling loop is for NFC-A.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static final int POLLING_LOOP_TYPE_A = 'A';
-
-    /**
-     * POLLING_LOOP_TYPE_B is the value associated with the key
-     * POLLING_LOOP_TYPE  in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
-     * when the polling loop is for NFC-B.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static final int POLLING_LOOP_TYPE_B = 'B';
-
-    /**
-     * POLLING_LOOP_TYPE_F is the value associated with the key
-     * POLLING_LOOP_TYPE  in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
-     * when the polling loop is for NFC-F.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static final int POLLING_LOOP_TYPE_F = 'F';
-
-    /**
-     * POLLING_LOOP_TYPE_ON is the value associated with the key
-     * POLLING_LOOP_TYPE  in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
-     * when the polling loop turns on.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static final int POLLING_LOOP_TYPE_ON = 'O';
-
-    /**
-     * POLLING_LOOP_TYPE_OFF is the value associated with the key
-     * POLLING_LOOP_TYPE  in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
-     * when the polling loop turns off.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static final int POLLING_LOOP_TYPE_OFF = 'X';
-
-    /**
-     * POLLING_LOOP_TYPE_UNKNOWN is the value associated with the key
-     * POLLING_LOOP_TYPE  in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
-     * when the polling loop frame isn't recognized.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    public static final int POLLING_LOOP_TYPE_UNKNOWN = 'U';
-
-    /**
-     * KEY_POLLING_LOOP_TYPE is the Bundle key for the type of
-     * polling loop frame in the Bundle included in MSG_POLLING_LOOP.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    private static final String KEY_POLLING_LOOP_TYPE = "android.nfc.cardemulation.TYPE";
-
-    /**
-     * KEY_POLLING_LOOP_DATA is the Bundle key for the raw data of captured from
-     * the polling loop frame in the Bundle included in MSG_POLLING_LOOP.
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    private static final String KEY_POLLING_LOOP_DATA = "android.nfc.cardemulation.DATA";
-
-    /**
-     * KEY_POLLING_LOOP_GAIN is the Bundle key for the field strength of
-     * the polling loop frame in the Bundle included in MSG_POLLING_LOOP.
-    */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    private static final String KEY_POLLING_LOOP_GAIN = "android.nfc.cardemulation.GAIN";
-
-    /**
-     * KEY_POLLING_LOOP_TIMESTAMP is the Bundle key for the timestamp of
-     * the polling loop frame in the Bundle included in MSG_POLLING_LOOP.
-    */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    private static final String KEY_POLLING_LOOP_TIMESTAMP = "android.nfc.cardemulation.TIMESTAMP";
-
-    /**
-     * KEY_POLLING_LOOP_TIMESTAMP is the Bundle key for whether this polling frame triggered
-     * autoTransact in the Bundle included in MSG_POLLING_LOOP.
-    */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-    private static final String KEY_POLLING_LOOP_TRIGGERED_AUTOTRANSACT =
-            "android.nfc.cardemulation.TRIGGERED_AUTOTRANSACT";
-
-
-    @PollingFrameType
-    private final int mType;
-    private final byte[] mData;
-    private final int mGain;
-    private final long mTimestamp;
-    private boolean mTriggeredAutoTransact;
-
-    public static final @NonNull Parcelable.Creator<PollingFrame> CREATOR =
-            new Parcelable.Creator<>() {
-                @Override
-                public PollingFrame createFromParcel(Parcel source) {
-                    return new PollingFrame(source.readBundle());
-                }
-
-                @Override
-                public PollingFrame[] newArray(int size) {
-                    return new PollingFrame[size];
-                }
-            };
-
-    private PollingFrame(Bundle frame) {
-        mType = frame.getInt(KEY_POLLING_LOOP_TYPE);
-        byte[] data = frame.getByteArray(KEY_POLLING_LOOP_DATA);
-        mData = (data == null) ? new byte[0] : data;
-        mGain = frame.getInt(KEY_POLLING_LOOP_GAIN, -1);
-        mTimestamp = frame.getLong(KEY_POLLING_LOOP_TIMESTAMP);
-        mTriggeredAutoTransact = frame.containsKey(KEY_POLLING_LOOP_TRIGGERED_AUTOTRANSACT)
-                && frame.getBoolean(KEY_POLLING_LOOP_TRIGGERED_AUTOTRANSACT);
-    }
-
-    /**
-     * Constructor for Polling Frames.
-     *
-     * @param type the type of the frame
-     * @param data a byte array of the data contained in the frame
-     * @param gain the vendor-specific gain of the field
-     * @param timestampMicros the timestamp in microseconds
-     * @param triggeredAutoTransact whether or not this frame triggered the device to start a
-     * transaction automatically
-     *
-     * @hide
-     */
-    public PollingFrame(@PollingFrameType int type, @Nullable byte[] data,
-            int gain, long timestampMicros, boolean triggeredAutoTransact) {
-        mType = type;
-        mData = data == null ? new byte[0] : data;
-        mGain = gain;
-        mTimestamp = timestampMicros;
-        mTriggeredAutoTransact = triggeredAutoTransact;
-    }
-
-    /**
-     * Returns the type of frame for this polling loop frame.
-     * The possible return values are:
-     * <ul>
-     *   <li>{@link #POLLING_LOOP_TYPE_ON}</li>
-     *   <li>{@link #POLLING_LOOP_TYPE_OFF}</li>
-     *   <li>{@link #POLLING_LOOP_TYPE_A}</li>
-     *   <li>{@link #POLLING_LOOP_TYPE_B}</li>
-     *   <li>{@link #POLLING_LOOP_TYPE_F}</li>
-     * </ul>
-     */
-    public @PollingFrameType int getType() {
-        return mType;
-    }
-
-    /**
-     * Returns the raw data from the polling type frame.
-     */
-    public @NonNull byte[] getData() {
-        return mData;
-    }
-
-    /**
-     * Returns the gain representing the field strength of the NFC field when this polling loop
-     * frame was observed.
-     * @return the gain or -1 if there is no gain measurement associated with this frame.
-     */
-    public int getVendorSpecificGain() {
-        return mGain;
-    }
-
-    /**
-     * Returns the timestamp of when the polling loop frame was observed, in microseconds. These
-     * timestamps are relative and should only be used for comparing the timing of frames relative
-     * to each other.
-     * @return the timestamp in microseconds
-     */
-    public long getTimestamp() {
-        return mTimestamp;
-    }
-
-    /**
-     * @hide
-     */
-    public void setTriggeredAutoTransact(boolean triggeredAutoTransact) {
-        mTriggeredAutoTransact = triggeredAutoTransact;
-    }
-
-    /**
-     * Returns whether this frame triggered the device to automatically disable observe mode and
-     * allow one transaction.
-     */
-    public boolean getTriggeredAutoTransact() {
-        return mTriggeredAutoTransact;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeBundle(toBundle());
-    }
-
-    /**
-     * @return a Bundle representing this frame
-     */
-    private Bundle toBundle() {
-        Bundle frame = new Bundle();
-        frame.putInt(KEY_POLLING_LOOP_TYPE, getType());
-        if (getVendorSpecificGain() != -1) {
-            frame.putInt(KEY_POLLING_LOOP_GAIN, (byte) getVendorSpecificGain());
-        }
-        frame.putByteArray(KEY_POLLING_LOOP_DATA, getData());
-        frame.putLong(KEY_POLLING_LOOP_TIMESTAMP, getTimestamp());
-        frame.putBoolean(KEY_POLLING_LOOP_TRIGGERED_AUTOTRANSACT, getTriggeredAutoTransact());
-        return frame;
-    }
-
-    @Override
-    public String toString() {
-        return "PollingFrame { Type: " + (char) getType()
-                + ", gain: " + getVendorSpecificGain()
-                + ", timestamp: " + Long.toUnsignedString(getTimestamp())
-                + ", data: [" + HexFormat.ofDelimiter(" ").formatHex(getData()) + "] }";
-    }
-}
diff --git a/nfc/java/android/nfc/cardemulation/Utils.java b/nfc/java/android/nfc/cardemulation/Utils.java
deleted file mode 100644
index 202e1cf..0000000
--- a/nfc/java/android/nfc/cardemulation/Utils.java
+++ /dev/null
@@ -1,37 +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 android.nfc.cardemulation;
-
-import android.annotation.NonNull;
-import android.content.ComponentName;
-import android.content.ComponentNameProto;
-import android.util.proto.ProtoOutputStream;
-
-/** @hide */
-public final class Utils {
-    private Utils() {
-    }
-
-    /** Copied from {@link ComponentName#dumpDebug(ProtoOutputStream, long)} */
-    public static void dumpDebugComponentName(
-            @NonNull ComponentName componentName, @NonNull ProtoOutputStream proto, long fieldId) {
-        final long token = proto.start(fieldId);
-        proto.write(ComponentNameProto.PACKAGE_NAME, componentName.getPackageName());
-        proto.write(ComponentNameProto.CLASS_NAME, componentName.getClassName());
-        proto.end(token);
-    }
-}
diff --git a/nfc/java/android/nfc/dta/NfcDta.java b/nfc/java/android/nfc/dta/NfcDta.java
deleted file mode 100644
index 8801662..0000000
--- a/nfc/java/android/nfc/dta/NfcDta.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2017 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 android.nfc.dta;
-
-import android.content.Context;
-import android.nfc.INfcDta;
-import android.nfc.NfcAdapter;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-
-/**
- * This class provides the primary API for DTA operations.
- * @hide
- */
-public final class NfcDta {
-    private static final String TAG = "NfcDta";
-
-    private static INfcDta sService;
-    private static HashMap<Context, NfcDta> sNfcDtas = new HashMap<Context, NfcDta>();
-
-    private final Context mContext;
-
-    private NfcDta(Context context, INfcDta service) {
-        mContext = context.getApplicationContext();
-        sService = service;
-    }
-
-    /**
-     * Helper to get an instance of this class.
-     *
-     * @param adapter A reference to an NfcAdapter object.
-     * @return
-     */
-    public static synchronized NfcDta getInstance(NfcAdapter adapter) {
-        if (adapter == null) throw new NullPointerException("NfcAdapter is null");
-        Context context = adapter.getContext();
-        if (context == null) {
-            Log.e(TAG, "NfcAdapter context is null.");
-            throw new UnsupportedOperationException();
-        }
-
-        NfcDta manager = sNfcDtas.get(context);
-        if (manager == null) {
-            INfcDta service = adapter.getNfcDtaInterface();
-            if (service == null) {
-                Log.e(TAG, "This device does not implement the INfcDta interface.");
-                throw new UnsupportedOperationException();
-            }
-            manager = new NfcDta(context, service);
-            sNfcDtas.put(context, manager);
-        }
-        return manager;
-    }
-
-    /**
-     * Enables DTA mode
-     *
-     * @return true/false if enabling was successful
-     */
-    public boolean enableDta() {
-        try {
-            sService.enableDta();
-        } catch (RemoteException e) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Disables DTA mode
-     *
-     * @return true/false if disabling was successful
-     */
-    public boolean disableDta() {
-        try {
-            sService.disableDta();
-        } catch (RemoteException e) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Enables Server
-     *
-     * @return true/false if enabling was successful
-     */
-    public boolean enableServer(String serviceName, int serviceSap, int miu,
-            int rwSize, int testCaseId) {
-        try {
-            return sService.enableServer(serviceName, serviceSap, miu, rwSize, testCaseId);
-        } catch (RemoteException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Disables Server
-     *
-     * @return true/false if disabling was successful
-     */
-    public boolean disableServer() {
-        try {
-            sService.disableServer();
-        } catch (RemoteException e) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Enables Client
-     *
-     * @return true/false if enabling was successful
-     */
-    public boolean enableClient(String serviceName, int miu, int rwSize,
-            int testCaseId) {
-        try {
-            return sService.enableClient(serviceName, miu, rwSize, testCaseId);
-        } catch (RemoteException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Disables client
-     *
-     * @return true/false if disabling was successful
-     */
-    public boolean disableClient() {
-        try {
-            sService.disableClient();
-        } catch (RemoteException e) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Registers Message Service
-     *
-     * @return true/false if registration was successful
-     */
-    public boolean registerMessageService(String msgServiceName) {
-        try {
-            return sService.registerMessageService(msgServiceName);
-        } catch (RemoteException e) {
-            return false;
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/package.html b/nfc/java/android/nfc/package.html
deleted file mode 100644
index 55c1d16..0000000
--- a/nfc/java/android/nfc/package.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides access to Near Field Communication (NFC) functionality, allowing applications to read
-NDEF message in NFC tags. A "tag" may actually be another device that appears as a tag.</p>
-
-<p>For more information, see the
-<a href="{@docRoot}guide/topics/connectivity/nfc/index.html">Near Field Communication</a> guide.</p>
-{@more}
-
-<p>Here's a summary of the classes:</p>
-
-<dl>
-  <dt>{@link android.nfc.NfcManager}</dt>
-  <dd>This is the high level manager, used to obtain this device's {@link android.nfc.NfcAdapter}. You can
-acquire an instance using {@link android.content.Context#getSystemService}.</dd>
-  <dt>{@link android.nfc.NfcAdapter}</dt>
-  <dd>This represents the device's NFC adapter, which is your entry-point to performing NFC
-operations. You can acquire an instance with {@link android.nfc.NfcManager#getDefaultAdapter}, or
-{@link android.nfc.NfcAdapter#getDefaultAdapter(android.content.Context)}.</dd>
-  <dt>{@link android.nfc.NdefMessage}</dt>
-  <dd>Represents an NDEF data message, which is the standard format in which "records"
-carrying data are transmitted between devices and tags. Your application can receive these
-messages from an {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} intent.</dd>
-  <dt>{@link android.nfc.NdefRecord}</dt>
-  <dd>Represents a record, which is delivered in a {@link android.nfc.NdefMessage} and describes the
-type of data being shared and carries the data itself.</dd>
-</dl>
-
-<p class="note"><strong>Note:</strong>
-Not all Android-powered devices provide NFC functionality.</p>
-
-</BODY>
-</HTML>
diff --git a/nfc/java/android/nfc/tech/BasicTagTechnology.java b/nfc/java/android/nfc/tech/BasicTagTechnology.java
deleted file mode 100644
index ae468fe..0000000
--- a/nfc/java/android/nfc/tech/BasicTagTechnology.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.nfc.TransceiveResult;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * A base class for tag technologies that are built on top of transceive().
- */
-abstract class BasicTagTechnology implements TagTechnology {
-    private static final String TAG = "NFC";
-
-    final Tag mTag;
-
-    boolean mIsConnected;
-    int mSelectedTechnology;
-
-    BasicTagTechnology(Tag tag, int tech) throws RemoteException {
-        mTag = tag;
-        mSelectedTechnology = tech;
-    }
-
-    @Override
-    public Tag getTag() {
-        return mTag;
-    }
-
-    /** Internal helper to throw IllegalStateException if the technology isn't connected */
-    void checkConnected() {
-       if ((mTag.getConnectedTechnology() != mSelectedTechnology) ||
-               (mTag.getConnectedTechnology() == -1)) {
-           throw new IllegalStateException("Call connect() first!");
-       }
-    }
-
-    @Override
-    public boolean isConnected() {
-        if (!mIsConnected) {
-            return false;
-        }
-
-        try {
-            return mTag.getTagService().isPresent(mTag.getServiceHandle());
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return false;
-        }
-    }
-
-    @Override
-    public void connect() throws IOException {
-        try {
-            int errorCode = mTag.getTagService().connect(mTag.getServiceHandle(),
-                    mSelectedTechnology);
-
-            if (errorCode == ErrorCodes.SUCCESS) {
-                // Store this in the tag object
-                if (!mTag.setConnectedTechnology(mSelectedTechnology)) {
-                    Log.e(TAG, "Close other technology first!");
-                    throw new IOException("Only one TagTechnology can be connected at a time.");
-                }
-                mIsConnected = true;
-            } else if (errorCode == ErrorCodes.ERROR_NOT_SUPPORTED) {
-                throw new UnsupportedOperationException("Connecting to " +
-                        "this technology is not supported by the NFC " +
-                        "adapter.");
-            } else {
-                throw new IOException();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            throw new IOException("NFC service died");
-        }
-    }
-
-    /** @hide */
-    @Override
-    public void reconnect() throws IOException {
-        if (!mIsConnected) {
-            throw new IllegalStateException("Technology not connected yet");
-        }
-
-        try {
-            int errorCode = mTag.getTagService().reconnect(mTag.getServiceHandle());
-
-            if (errorCode != ErrorCodes.SUCCESS) {
-                mIsConnected = false;
-                mTag.setTechnologyDisconnected();
-                throw new IOException();
-            }
-        } catch (RemoteException e) {
-            mIsConnected = false;
-            mTag.setTechnologyDisconnected();
-            Log.e(TAG, "NFC service dead", e);
-            throw new IOException("NFC service died");
-        }
-    }
-
-    @Override
-    public void close() throws IOException {
-        try {
-            /* Note that we don't want to physically disconnect the tag,
-             * but just reconnect to it to reset its state
-             */
-            mTag.getTagService().resetTimeouts();
-            mTag.getTagService().reconnect(mTag.getServiceHandle());
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        } finally {
-            mIsConnected = false;
-            mTag.setTechnologyDisconnected();
-        }
-    }
-
-    /** Internal getMaxTransceiveLength() */
-    int getMaxTransceiveLengthInternal() {
-        try {
-            return mTag.getTagService().getMaxTransceiveLength(mSelectedTechnology);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return 0;
-        }
-    }
-    /** Internal transceive */
-    byte[] transceive(byte[] data, boolean raw) throws IOException {
-        checkConnected();
-
-        try {
-            TransceiveResult result = mTag.getTagService().transceive(mTag.getServiceHandle(),
-                    data, raw);
-            if (result == null) {
-                throw new IOException("transceive failed");
-            } else {
-                return result.getResponseOrThrow();
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            throw new IOException("NFC service died");
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/IsoDep.java b/nfc/java/android/nfc/tech/IsoDep.java
deleted file mode 100644
index 0ba0c5a..0000000
--- a/nfc/java/android/nfc/tech/IsoDep.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire an {@link IsoDep} object using {@link #get}.
- * <p>The primary ISO-DEP I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- * <p>Tags that enumerate the {@link IsoDep} technology in {@link Tag#getTechList}
- * will also enumerate
- * {@link NfcA} or {@link NfcB} (since IsoDep builds on top of either of these).
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class IsoDep extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /** @hide */
-    public static final String EXTRA_HI_LAYER_RESP = "hiresp";
-    /** @hide */
-    public static final String EXTRA_HIST_BYTES = "histbytes";
-
-    private byte[] mHiLayerResponse = null;
-    private byte[] mHistBytes = null;
-
-    /**
-     * Get an instance of {@link IsoDep} for the given tag.
-     * <p>Does not cause any RF activity and does not block.
-     * <p>Returns null if {@link IsoDep} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag does not support ISO-DEP.
-     *
-     * @param tag an ISO-DEP compatible tag
-     * @return ISO-DEP object
-     */
-    public static IsoDep get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.ISO_DEP)) return null;
-        try {
-            return new IsoDep(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public IsoDep(Tag tag)
-            throws RemoteException {
-        super(tag, TagTechnology.ISO_DEP);
-        Bundle extras = tag.getTechExtras(TagTechnology.ISO_DEP);
-        if (extras != null) {
-            mHiLayerResponse = extras.getByteArray(EXTRA_HI_LAYER_RESP);
-            mHistBytes = extras.getByteArray(EXTRA_HIST_BYTES);
-        }
-    }
-
-    /**
-     * Set the timeout of {@link #transceive} in milliseconds.
-     * <p>The timeout only applies to ISO-DEP {@link #transceive}, and is
-     * reset to a default value when {@link #close} is called.
-     * <p>Setting a longer timeout may be useful when performing
-     * transactions that require a long processing time on the tag
-     * such as key generation.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param timeout timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void setTimeout(int timeout) {
-        try {
-            int err = mTag.getTagService().setTimeout(TagTechnology.ISO_DEP, timeout);
-            if (err != ErrorCodes.SUCCESS) {
-                throw new IllegalArgumentException("The supplied timeout is not valid");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-
-    /**
-     * Get the current timeout for {@link #transceive} in milliseconds.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public int getTimeout() {
-        try {
-            return mTag.getTagService().getTimeout(TagTechnology.ISO_DEP);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return 0;
-        }
-    }
-
-    /**
-     * Return the ISO-DEP historical bytes for {@link NfcA} tags.
-     * <p>Does not cause any RF activity and does not block.
-     * <p>The historical bytes can be used to help identify a tag. They are present
-     * only on {@link IsoDep} tags that are based on {@link NfcA} RF technology.
-     * If this tag is not {@link NfcA} then null is returned.
-     * <p>In ISO 14443-4 terminology, the historical bytes are a subset of the RATS
-     * response.
-     *
-     * @return ISO-DEP historical bytes, or null if this is not a {@link NfcA} tag
-     */
-    public byte[] getHistoricalBytes() {
-        return mHistBytes;
-    }
-
-    /**
-     * Return the higher layer response bytes for {@link NfcB} tags.
-     * <p>Does not cause any RF activity and does not block.
-     * <p>The higher layer response bytes can be used to help identify a tag.
-     * They are present only on {@link IsoDep} tags that are based on {@link NfcB}
-     * RF technology. If this tag is not {@link NfcB} then null is returned.
-     * <p>In ISO 14443-4 terminology, the higher layer bytes are a subset of the
-     * ATTRIB response.
-     *
-     * @return ISO-DEP historical bytes, or null if this is not a {@link NfcB} tag
-     */
-    public byte[] getHiLayerResponse() {
-        return mHiLayerResponse;
-    }
-
-    /**
-     * Send raw ISO-DEP data to the tag and receive the response.
-     *
-     * <p>Applications must only send the INF payload, and not the start of frame and
-     * end of frame indicators. Applications do not need to fragment the payload, it
-     * will be automatically fragmented and defragmented by {@link #transceive} if
-     * it exceeds FSD/FSC limits.
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param data command bytes to send, must not be null
-     * @return response bytes received, will not be null
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or this operation is canceled
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-
-    /**
-     * <p>Standard APDUs have a 1-byte length field, allowing a maximum of
-     * 255 payload bytes, which results in a maximum APDU length of 261 bytes.
-     *
-     * <p>Extended length APDUs have a 3-byte length field, allowing 65535
-     * payload bytes.
-     *
-     * <p>Some NFC adapters, like the one used in the Nexus S and the Galaxy Nexus
-     * do not support extended length APDUs. They are expected to be well-supported
-     * in the future though. Use this method to check for extended length APDU
-     * support.
-     *
-     * @return whether the NFC adapter on this device supports extended length APDUs.
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public boolean isExtendedLengthApduSupported() {
-        try {
-            return mTag.getTagService().getExtendedLengthApdusSupported();
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return false;
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/MifareClassic.java b/nfc/java/android/nfc/tech/MifareClassic.java
deleted file mode 100644
index 26f54e6..0000000
--- a/nfc/java/android/nfc/tech/MifareClassic.java
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.nfc.TagLostException;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * Provides access to MIFARE Classic properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link MifareClassic} object using {@link #get}.
- *
- * <p>MIFARE Classic is also known as MIFARE Standard.
- * <p>MIFARE Classic tags are divided into sectors, and each sector is sub-divided into
- * blocks. Block size is always 16 bytes ({@link #BLOCK_SIZE}. Sector size varies.
- * <ul>
- * <li>MIFARE Classic Mini are 320 bytes ({@link #SIZE_MINI}), with 5 sectors each of 4 blocks.
- * <li>MIFARE Classic 1k are 1024 bytes ({@link #SIZE_1K}), with 16 sectors each of 4 blocks.
- * <li>MIFARE Classic 2k are 2048 bytes ({@link #SIZE_2K}), with 32 sectors each of 4 blocks.
- * <li>MIFARE Classic 4k are 4096 bytes ({@link #SIZE_4K}). The first 32 sectors contain 4 blocks
- * and the last 8 sectors contain 16 blocks.
- * </ul>
- *
- * <p>MIFARE Classic tags require authentication on a per-sector basis before any
- * other I/O operations on that sector can be performed. There are two keys per sector,
- * and ACL bits determine what I/O operations are allowed on that sector after
- * authenticating with a key. {@see #authenticateSectorWithKeyA} and
- * {@see #authenticateSectorWithKeyB}.
- *
- * <p>Three well-known authentication keys are defined in this class:
- * {@link #KEY_DEFAULT}, {@link #KEY_MIFARE_APPLICATION_DIRECTORY},
- * {@link #KEY_NFC_FORUM}.
- * <ul>
- * <li>{@link #KEY_DEFAULT} is the default factory key for MIFARE Classic.
- * <li>{@link #KEY_MIFARE_APPLICATION_DIRECTORY} is the well-known key for
- * MIFARE Classic cards that have been formatted according to the
- * MIFARE Application Directory (MAD) specification.
- * <li>{@link #KEY_NFC_FORUM} is the well-known key for MIFARE Classic cards that
- * have been formatted according to the NXP specification for NDEF on MIFARE Classic.
- *
- * <p>Implementation of this class on a Android NFC device is optional.
- * If it is not implemented, then
- * {@link MifareClassic} will never be enumerated in {@link Tag#getTechList}.
- * If it is enumerated, then all {@link MifareClassic} I/O operations will be supported,
- * and {@link Ndef#MIFARE_CLASSIC} NDEF tags will also be supported. In either case,
- * {@link NfcA} will also be enumerated on the tag, because all MIFARE Classic tags are also
- * {@link NfcA}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class MifareClassic extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /**
-     * The default factory key.
-     */
-    public static final byte[] KEY_DEFAULT =
-            {(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
-    /**
-     * The well-known key for tags formatted according to the
-     * MIFARE Application Directory (MAD) specification.
-     */
-    public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY =
-            {(byte)0xA0,(byte)0xA1,(byte)0xA2,(byte)0xA3,(byte)0xA4,(byte)0xA5};
-    /**
-     * The well-known key for tags formatted according to the
-     * NDEF on MIFARE Classic specification.
-     */
-    public static final byte[] KEY_NFC_FORUM =
-            {(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7};
-
-    /** A MIFARE Classic compatible card of unknown type */
-    public static final int TYPE_UNKNOWN = -1;
-    /** A MIFARE Classic tag */
-    public static final int TYPE_CLASSIC = 0;
-    /** A MIFARE Plus tag */
-    public static final int TYPE_PLUS = 1;
-    /** A MIFARE Pro tag */
-    public static final int TYPE_PRO = 2;
-
-    /** Tag contains 16 sectors, each with 4 blocks. */
-    public static final int SIZE_1K = 1024;
-    /** Tag contains 32 sectors, each with 4 blocks. */
-    public static final int SIZE_2K = 2048;
-    /**
-     * Tag contains 40 sectors. The first 32 sectors contain 4 blocks and the last 8 sectors
-     * contain 16 blocks.
-     */
-    public static final int SIZE_4K = 4096;
-    /** Tag contains 5 sectors, each with 4 blocks. */
-    public static final int SIZE_MINI = 320;
-
-    /** Size of a MIFARE Classic block (in bytes) */
-    public static final int BLOCK_SIZE = 16;
-
-    private static final int MAX_BLOCK_COUNT = 256;
-    private static final int MAX_SECTOR_COUNT = 40;
-
-    private boolean mIsEmulated;
-    private int mType;
-    private int mSize;
-
-    /**
-     * Get an instance of {@link MifareClassic} for the given tag.
-     * <p>Does not cause any RF activity and does not block.
-     * <p>Returns null if {@link MifareClassic} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag is not MIFARE Classic compatible, or this Android
-     * device does not support MIFARE Classic.
-     *
-     * @param tag an MIFARE Classic compatible tag
-     * @return MIFARE Classic object
-     */
-    public static MifareClassic get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.MIFARE_CLASSIC)) return null;
-        try {
-            return new MifareClassic(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public MifareClassic(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.MIFARE_CLASSIC);
-
-        NfcA a = NfcA.get(tag);  // MIFARE Classic is always based on NFC a
-
-        mIsEmulated = false;
-
-        switch (a.getSak()) {
-        case 0x01:
-        case 0x08:
-            mType = TYPE_CLASSIC;
-            mSize = SIZE_1K;
-            break;
-        case 0x09:
-            mType = TYPE_CLASSIC;
-            mSize = SIZE_MINI;
-            break;
-        case 0x10:
-            mType = TYPE_PLUS;
-            mSize = SIZE_2K;
-            // SecLevel = SL2
-            break;
-        case 0x11:
-            mType = TYPE_PLUS;
-            mSize = SIZE_4K;
-            // Seclevel = SL2
-            break;
-        case 0x18:
-            mType = TYPE_CLASSIC;
-            mSize = SIZE_4K;
-            break;
-        case 0x28:
-            mType = TYPE_CLASSIC;
-            mSize = SIZE_1K;
-            mIsEmulated = true;
-            break;
-        case 0x38:
-            mType = TYPE_CLASSIC;
-            mSize = SIZE_4K;
-            mIsEmulated = true;
-            break;
-        case 0x88:
-            mType = TYPE_CLASSIC;
-            mSize = SIZE_1K;
-            // NXP-tag: false
-            break;
-        case 0x98:
-        case 0xB8:
-            mType = TYPE_PRO;
-            mSize = SIZE_4K;
-            break;
-        default:
-            // Stack incorrectly reported a MifareClassic. We cannot handle this
-            // gracefully - we have no idea of the memory layout. Bail.
-            throw new RuntimeException(
-                    "Tag incorrectly enumerated as MIFARE Classic, SAK = " + a.getSak());
-        }
-    }
-
-    /**
-     * Return the type of this MIFARE Classic compatible tag.
-     * <p>One of {@link #TYPE_UNKNOWN}, {@link #TYPE_CLASSIC}, {@link #TYPE_PLUS} or
-     * {@link #TYPE_PRO}.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return type
-     */
-    public int getType() {
-        return mType;
-    }
-
-    /**
-     * Return the size of the tag in bytes
-     * <p>One of {@link #SIZE_MINI}, {@link #SIZE_1K}, {@link #SIZE_2K}, {@link #SIZE_4K}.
-     * These constants are equal to their respective size in bytes.
-     * <p>Does not cause any RF activity and does not block.
-     * @return size in bytes
-     */
-    public int getSize() {
-        return mSize;
-    }
-
-    /**
-     * Return true if the tag is emulated, determined at discovery time.
-     * These are actually smart-cards that emulate a MIFARE Classic interface.
-     * They can be treated identically to a MIFARE Classic tag.
-     * @hide
-     */
-    public boolean isEmulated() {
-        return mIsEmulated;
-    }
-
-    /**
-     * Return the number of MIFARE Classic sectors.
-     * <p>Does not cause any RF activity and does not block.
-     * @return number of sectors
-     */
-    public int getSectorCount() {
-        switch (mSize) {
-        case SIZE_1K:
-            return 16;
-        case SIZE_2K:
-            return 32;
-        case SIZE_4K:
-            return 40;
-        case SIZE_MINI:
-            return 5;
-        default:
-            return 0;
-        }
-    }
-
-    /**
-     * Return the total number of MIFARE Classic blocks.
-     * <p>Does not cause any RF activity and does not block.
-     * @return total number of blocks
-     */
-    public int getBlockCount() {
-        return mSize / BLOCK_SIZE;
-    }
-
-    /**
-     * Return the number of blocks in the given sector.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param sectorIndex index of sector, starting from 0
-     * @return number of blocks in the sector
-     */
-    public int getBlockCountInSector(int sectorIndex) {
-        validateSector(sectorIndex);
-
-        if (sectorIndex < 32) {
-            return 4;
-        } else {
-            return 16;
-        }
-    }
-
-    /**
-     * Return the sector that contains a given block.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param blockIndex index of block to lookup, starting from 0
-     * @return sector index that contains the block
-     */
-    public int blockToSector(int blockIndex) {
-        validateBlock(blockIndex);
-
-        if (blockIndex < 32 * 4) {
-            return blockIndex / 4;
-        } else {
-            return 32 + (blockIndex - 32 * 4) / 16;
-        }
-    }
-
-    /**
-     * Return the first block of a given sector.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param sectorIndex index of sector to lookup, starting from 0
-     * @return block index of first block in sector
-     */
-    public int sectorToBlock(int sectorIndex) {
-        if (sectorIndex < 32) {
-            return sectorIndex * 4;
-        } else {
-            return 32 * 4 + (sectorIndex - 32) * 16;
-        }
-    }
-
-    /**
-     * Authenticate a sector with key A.
-     *
-     * <p>Successful authentication of a sector with key A enables other
-     * I/O operations on that sector. The set of operations granted by key A
-     * key depends on the ACL bits set in that sector. For more information
-     * see the MIFARE Classic specification on <a href="http://www.nxp.com">http://www.nxp.com</a>.
-     *
-     * <p>A failed authentication attempt causes an implicit reconnection to the
-     * tag, so authentication to other sectors will be lost.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param sectorIndex index of sector to authenticate, starting from 0
-     * @param key 6-byte authentication key
-     * @return true on success, false on authentication failure
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public boolean authenticateSectorWithKeyA(int sectorIndex, byte[] key) throws IOException {
-        return authenticate(sectorIndex, key, true);
-    }
-
-    /**
-     * Authenticate a sector with key B.
-     *
-     * <p>Successful authentication of a sector with key B enables other
-     * I/O operations on that sector. The set of operations granted by key B
-     * depends on the ACL bits set in that sector. For more information
-     * see the MIFARE Classic specification on <a href="http://www.nxp.com">http://www.nxp.com</a>.
-     *
-     * <p>A failed authentication attempt causes an implicit reconnection to the
-     * tag, so authentication to other sectors will be lost.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param sectorIndex index of sector to authenticate, starting from 0
-     * @param key 6-byte authentication key
-     * @return true on success, false on authentication failure
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public boolean authenticateSectorWithKeyB(int sectorIndex, byte[] key) throws IOException {
-        return authenticate(sectorIndex, key, false);
-    }
-
-    private boolean authenticate(int sector, byte[] key, boolean keyA) throws IOException {
-        validateSector(sector);
-        checkConnected();
-
-        byte[] cmd = new byte[12];
-
-        // First byte is the command
-        if (keyA) {
-            cmd[0] = 0x60; // phHal_eMifareAuthentA
-        } else {
-            cmd[0] = 0x61; // phHal_eMifareAuthentB
-        }
-
-        // Second byte is block address
-        // Authenticate command takes a block address. Authenticating a block
-        // of a sector will authenticate the entire sector.
-        cmd[1] = (byte) sectorToBlock(sector);
-
-        // Next 4 bytes are last 4 bytes of UID
-        byte[] uid = getTag().getId();
-        System.arraycopy(uid, uid.length - 4, cmd, 2, 4);
-
-        // Next 6 bytes are key
-        System.arraycopy(key, 0, cmd, 6, 6);
-
-        try {
-            if (transceive(cmd, false) != null) {
-                return true;
-            }
-        } catch (TagLostException e) {
-            throw e;
-        } catch (IOException e) {
-            // No need to deal with, will return false anyway
-        }
-        return false;
-    }
-
-    /**
-     * Read 16-byte block.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param blockIndex index of block to read, starting from 0
-     * @return 16 byte block
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public byte[] readBlock(int blockIndex) throws IOException {
-        validateBlock(blockIndex);
-        checkConnected();
-
-        byte[] cmd = { 0x30, (byte) blockIndex };
-        return transceive(cmd, false);
-    }
-
-    /**
-     * Write 16-byte block.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param blockIndex index of block to write, starting from 0
-     * @param data 16 bytes of data to write
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public void writeBlock(int blockIndex, byte[] data) throws IOException {
-        validateBlock(blockIndex);
-        checkConnected();
-        if (data.length != 16) {
-            throw new IllegalArgumentException("must write 16-bytes");
-        }
-
-        byte[] cmd = new byte[data.length + 2];
-        cmd[0] = (byte) 0xA0; // MF write command
-        cmd[1] = (byte) blockIndex;
-        System.arraycopy(data, 0, cmd, 2, data.length);
-
-        transceive(cmd, false);
-    }
-
-    /**
-     * Increment a value block, storing the result in the temporary block on the tag.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param blockIndex index of block to increment, starting from 0
-     * @param value non-negative to increment by
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public void increment(int blockIndex, int value) throws IOException {
-        validateBlock(blockIndex);
-        validateValueOperand(value);
-        checkConnected();
-
-        ByteBuffer cmd = ByteBuffer.allocate(6);
-        cmd.order(ByteOrder.LITTLE_ENDIAN);
-        cmd.put( (byte) 0xC1 );
-        cmd.put( (byte) blockIndex );
-        cmd.putInt(value);
-
-        transceive(cmd.array(), false);
-    }
-
-    /**
-     * Decrement a value block, storing the result in the temporary block on the tag.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param blockIndex index of block to decrement, starting from 0
-     * @param value non-negative to decrement by
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public void decrement(int blockIndex, int value) throws IOException {
-        validateBlock(blockIndex);
-        validateValueOperand(value);
-        checkConnected();
-
-        ByteBuffer cmd = ByteBuffer.allocate(6);
-        cmd.order(ByteOrder.LITTLE_ENDIAN);
-        cmd.put( (byte) 0xC0 );
-        cmd.put( (byte) blockIndex );
-        cmd.putInt(value);
-
-        transceive(cmd.array(), false);
-    }
-
-    /**
-     * Copy from the temporary block to a value block.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param blockIndex index of block to copy to
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public void transfer(int blockIndex) throws IOException {
-        validateBlock(blockIndex);
-        checkConnected();
-
-        byte[] cmd = { (byte) 0xB0, (byte) blockIndex };
-
-        transceive(cmd, false);
-    }
-
-    /**
-     * Copy from a value block to the temporary block.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param blockIndex index of block to copy from
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public void restore(int blockIndex) throws IOException {
-        validateBlock(blockIndex);
-        checkConnected();
-
-        byte[] cmd = { (byte) 0xC2, (byte) blockIndex };
-
-        transceive(cmd, false);
-    }
-
-    /**
-     * Send raw NfcA data to a tag and receive the response.
-     *
-     * <p>This is equivalent to connecting to this tag via {@link NfcA}
-     * and calling {@link NfcA#transceive}. Note that all MIFARE Classic
-     * tags are based on {@link NfcA} technology.
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @see NfcA#transceive
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-
-    /**
-     * Set the {@link #transceive} timeout in milliseconds.
-     *
-     * <p>The timeout only applies to {@link #transceive} on this object,
-     * and is reset to a default value when {@link #close} is called.
-     *
-     * <p>Setting a longer timeout may be useful when performing
-     * transactions that require a long processing time on the tag
-     * such as key generation.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param timeout timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void setTimeout(int timeout) {
-        try {
-            int err = mTag.getTagService().setTimeout(TagTechnology.MIFARE_CLASSIC, timeout);
-            if (err != ErrorCodes.SUCCESS) {
-                throw new IllegalArgumentException("The supplied timeout is not valid");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-
-    /**
-     * Get the current {@link #transceive} timeout in milliseconds.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public int getTimeout() {
-        try {
-            return mTag.getTagService().getTimeout(TagTechnology.MIFARE_CLASSIC);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return 0;
-        }
-    }
-
-    private static void validateSector(int sector) {
-        // Do not be too strict on upper bounds checking, since some cards
-        // have more addressable memory than they report. For example,
-        // MIFARE Plus 2k cards will appear as MIFARE Classic 1k cards when in
-        // MIFARE Classic compatibility mode.
-        // Note that issuing a command to an out-of-bounds block is safe - the
-        // tag should report error causing IOException. This validation is a
-        // helper to guard against obvious programming mistakes.
-        if (sector < 0 || sector >= MAX_SECTOR_COUNT) {
-            throw new IndexOutOfBoundsException("sector out of bounds: " + sector);
-        }
-    }
-
-    private static void validateBlock(int block) {
-        // Just looking for obvious out of bounds...
-        if (block < 0 || block >= MAX_BLOCK_COUNT) {
-            throw new IndexOutOfBoundsException("block out of bounds: " + block);
-        }
-    }
-
-    private static void validateValueOperand(int value) {
-        if (value < 0) {
-            throw new IllegalArgumentException("value operand negative");
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/MifareUltralight.java b/nfc/java/android/nfc/tech/MifareUltralight.java
deleted file mode 100644
index c0416a3..0000000
--- a/nfc/java/android/nfc/tech/MifareUltralight.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.nfc.TagLostException;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-//TOOD: Ultralight C 3-DES authentication, one-way counter
-
-/**
- * Provides access to MIFARE Ultralight properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link MifareUltralight} object using {@link #get}.
- *
- * <p>MIFARE Ultralight compatible tags have 4 byte pages {@link #PAGE_SIZE}.
- * The primary operations on an Ultralight tag are {@link #readPages} and
- * {@link #writePage}.
- *
- * <p>The original MIFARE Ultralight consists of a 64 byte EEPROM. The first
- * 4 pages are for the OTP area, manufacturer data, and locking bits. They are
- * readable and some bits are writable. The final 12 pages are the user
- * read/write area. For more information see the NXP data sheet MF0ICU1.
- *
- * <p>The MIFARE Ultralight C consists of a 192 byte EEPROM. The first 4 pages
- * are for OTP, manufacturer data, and locking bits. The next 36 pages are the
- * user read/write area. The next 4 pages are additional locking bits, counters
- * and authentication configuration and are readable. The final 4 pages are for
- * the authentication key and are not readable. For more information see the
- * NXP data sheet MF0ICU2.
- *
- * <p>Implementation of this class on a Android NFC device is optional.
- * If it is not implemented, then
- * {@link MifareUltralight} will never be enumerated in {@link Tag#getTechList}.
- * If it is enumerated, then all {@link MifareUltralight} I/O operations will be supported.
- * In either case, {@link NfcA} will also be enumerated on the tag,
- * because all MIFARE Ultralight tags are also {@link NfcA} tags.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class MifareUltralight extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /** A MIFARE Ultralight compatible tag of unknown type */
-    public static final int TYPE_UNKNOWN = -1;
-    /** A MIFARE Ultralight tag */
-    public static final int TYPE_ULTRALIGHT = 1;
-    /** A MIFARE Ultralight C tag */
-    public static final int TYPE_ULTRALIGHT_C = 2;
-
-    /** Size of a MIFARE Ultralight page in bytes */
-    public static final int PAGE_SIZE = 4;
-
-    private static final int NXP_MANUFACTURER_ID = 0x04;
-    private static final int MAX_PAGE_COUNT = 256;
-
-    /** @hide */
-    public static final String EXTRA_IS_UL_C = "isulc";
-
-    private int mType;
-
-    /**
-     * Get an instance of {@link MifareUltralight} for the given tag.
-     * <p>Returns null if {@link MifareUltralight} was not enumerated in
-     * {@link Tag#getTechList} - this indicates the tag is not MIFARE
-     * Ultralight compatible, or that this Android
-     * device does not implement MIFARE Ultralight.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an MIFARE Ultralight compatible tag
-     * @return MIFARE Ultralight object
-     */
-    public static MifareUltralight get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.MIFARE_ULTRALIGHT)) return null;
-        try {
-            return new MifareUltralight(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public MifareUltralight(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.MIFARE_ULTRALIGHT);
-
-        // Check if this could actually be a MIFARE
-        NfcA a = NfcA.get(tag);
-
-        mType = TYPE_UNKNOWN;
-
-        if (a.getSak() == 0x00 && tag.getId()[0] == NXP_MANUFACTURER_ID) {
-            Bundle extras = tag.getTechExtras(TagTechnology.MIFARE_ULTRALIGHT);
-            if (extras.getBoolean(EXTRA_IS_UL_C)) {
-                mType = TYPE_ULTRALIGHT_C;
-            } else {
-                mType = TYPE_ULTRALIGHT;
-            }
-        }
-    }
-
-    /**
-     * Return the MIFARE Ultralight type of the tag.
-     * <p>One of {@link #TYPE_ULTRALIGHT} or {@link #TYPE_ULTRALIGHT_C} or
-     * {@link #TYPE_UNKNOWN}.
-     * <p>Depending on how the tag has been formatted, it can be impossible
-     * to accurately classify between original MIFARE Ultralight and
-     * Ultralight C. So treat this method as a hint.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return the type
-     */
-    public int getType() {
-        return mType;
-    }
-
-    /**
-     * Read 4 pages (16 bytes).
-     *
-     * <p>The MIFARE Ultralight protocol always reads 4 pages at a time, to
-     * reduce the number of commands required to read an entire tag.
-     * <p>If a read spans past the last readable block, then the tag will
-     * return pages that have been wrapped back to the first blocks. MIFARE
-     * Ultralight tags have readable blocks 0x00 through 0x0F. So a read to
-     * block offset 0x0E would return blocks 0x0E, 0x0F, 0x00, 0x01. MIFARE
-     * Ultralight C tags have readable blocks 0x00 through 0x2B. So a read to
-     * block 0x2A would return blocks 0x2A, 0x2B, 0x00, 0x01.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param pageOffset index of first page to read, starting from 0
-     * @return 4 pages (16 bytes)
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public byte[] readPages(int pageOffset) throws IOException {
-        validatePageIndex(pageOffset);
-        checkConnected();
-
-        byte[] cmd = { 0x30, (byte) pageOffset};
-        return transceive(cmd, false);
-    }
-
-    /**
-     * Write 1 page (4 bytes).
-     *
-     * <p>The MIFARE Ultralight protocol always writes 1 page at a time, to
-     * minimize EEPROM write cycles.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param pageOffset index of page to write, starting from 0
-     * @param data 4 bytes to write
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     */
-    public void writePage(int pageOffset, byte[] data) throws IOException {
-        validatePageIndex(pageOffset);
-        checkConnected();
-
-        byte[] cmd = new byte[data.length + 2];
-        cmd[0] = (byte) 0xA2;
-        cmd[1] = (byte) pageOffset;
-        System.arraycopy(data, 0, cmd, 2, data.length);
-
-        transceive(cmd, false);
-    }
-
-    /**
-     * Send raw NfcA data to a tag and receive the response.
-     *
-     * <p>This is equivalent to connecting to this tag via {@link NfcA}
-     * and calling {@link NfcA#transceive}. Note that all MIFARE Classic
-     * tags are based on {@link NfcA} technology.
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @see NfcA#transceive
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-
-    /**
-     * Set the {@link #transceive} timeout in milliseconds.
-     *
-     * <p>The timeout only applies to {@link #transceive} on this object,
-     * and is reset to a default value when {@link #close} is called.
-     *
-     * <p>Setting a longer timeout may be useful when performing
-     * transactions that require a long processing time on the tag
-     * such as key generation.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param timeout timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void setTimeout(int timeout) {
-        try {
-            int err = mTag.getTagService().setTimeout(
-                    TagTechnology.MIFARE_ULTRALIGHT, timeout);
-            if (err != ErrorCodes.SUCCESS) {
-                throw new IllegalArgumentException("The supplied timeout is not valid");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-
-    /**
-     * Get the current {@link #transceive} timeout in milliseconds.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public int getTimeout() {
-        try {
-            return mTag.getTagService().getTimeout(TagTechnology.MIFARE_ULTRALIGHT);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return 0;
-        }
-    }
-
-    private static void validatePageIndex(int pageIndex) {
-        // Do not be too strict on upper bounds checking, since some cards
-        // may have more addressable memory than they report.
-        // Note that issuing a command to an out-of-bounds block is safe - the
-        // tag will wrap the read to an addressable area. This validation is a
-        // helper to guard against obvious programming mistakes.
-        if (pageIndex < 0 || pageIndex >= MAX_PAGE_COUNT) {
-            throw new IndexOutOfBoundsException("page out of bounds: " + pageIndex);
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/Ndef.java b/nfc/java/android/nfc/tech/Ndef.java
deleted file mode 100644
index 7d83f15..0000000
--- a/nfc/java/android/nfc/tech/Ndef.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.FormatException;
-import android.nfc.INfcTag;
-import android.nfc.NdefMessage;
-import android.nfc.Tag;
-import android.nfc.TagLostException;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provides access to NDEF content and operations on a {@link Tag}.
- *
- * <p>Acquire a {@link Ndef} object using {@link #get}.
- *
- * <p>NDEF is an NFC Forum data format. The data formats are implemented in
- * {@link android.nfc.NdefMessage} and
- * {@link android.nfc.NdefRecord}. This class provides methods to
- * retrieve and modify the {@link android.nfc.NdefMessage}
- * on a tag.
- *
- * <p>There are currently four NFC Forum standardized tag types that can be
- * formatted to contain NDEF data.
- * <ul>
- * <li>NFC Forum Type 1 Tag ({@link #NFC_FORUM_TYPE_1}), such as the Innovision Topaz
- * <li>NFC Forum Type 2 Tag ({@link #NFC_FORUM_TYPE_2}), such as the NXP MIFARE Ultralight
- * <li>NFC Forum Type 3 Tag ({@link #NFC_FORUM_TYPE_3}), such as Sony Felica
- * <li>NFC Forum Type 4 Tag ({@link #NFC_FORUM_TYPE_4}), such as NXP MIFARE Desfire
- * </ul>
- * It is mandatory for all Android devices with NFC to correctly enumerate
- * {@link Ndef} on NFC Forum Tag Types 1-4, and implement all NDEF operations
- * as defined in this class.
- *
- * <p>Some vendors have their own well defined specifications for storing NDEF data
- * on tags that do not fall into the above categories. Android devices with NFC
- * should enumerate and implement {@link Ndef} under these vendor specifications
- * where possible, but it is not mandatory. {@link #getType} returns a String
- * describing this specification, for example {@link #MIFARE_CLASSIC} is
- * <code>com.nxp.ndef.mifareclassic</code>.
- *
- * <p>Android devices that support MIFARE Classic must also correctly
- * implement {@link Ndef} on MIFARE Classic tags formatted to NDEF.
- *
- * <p>For guaranteed compatibility across all Android devices with NFC, it is
- * recommended to use NFC Forum Types 1-4 in new deployments of NFC tags
- * with NDEF payload. Vendor NDEF formats will not work on all Android devices.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class Ndef extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /** @hide */
-    public static final int NDEF_MODE_READ_ONLY = 1;
-    /** @hide */
-    public static final int NDEF_MODE_READ_WRITE = 2;
-    /** @hide */
-    public static final int NDEF_MODE_UNKNOWN = 3;
-
-    /** @hide */
-    public static final String EXTRA_NDEF_MSG = "ndefmsg";
-
-    /** @hide */
-    public static final String EXTRA_NDEF_MAXLENGTH = "ndefmaxlength";
-
-    /** @hide */
-    public static final String EXTRA_NDEF_CARDSTATE = "ndefcardstate";
-
-    /** @hide */
-    public static final String EXTRA_NDEF_TYPE = "ndeftype";
-
-    /** @hide */
-    public static final int TYPE_OTHER = -1;
-    /** @hide */
-    public static final int TYPE_1 = 1;
-    /** @hide */
-    public static final int TYPE_2 = 2;
-    /** @hide */
-    public static final int TYPE_3 = 3;
-    /** @hide */
-    public static final int TYPE_4 = 4;
-    /** @hide */
-    public static final int TYPE_MIFARE_CLASSIC = 101;
-    /** @hide */
-    public static final int TYPE_ICODE_SLI = 102;
-
-    /** @hide */
-    public static final String UNKNOWN = "android.ndef.unknown";
-
-    /** NFC Forum Tag Type 1 */
-    public static final String NFC_FORUM_TYPE_1 = "org.nfcforum.ndef.type1";
-    /** NFC Forum Tag Type 2 */
-    public static final String NFC_FORUM_TYPE_2 = "org.nfcforum.ndef.type2";
-    /** NFC Forum Tag Type 3 */
-    public static final String NFC_FORUM_TYPE_3 = "org.nfcforum.ndef.type3";
-    /** NFC Forum Tag Type 4 */
-    public static final String NFC_FORUM_TYPE_4 = "org.nfcforum.ndef.type4";
-    /** NDEF on MIFARE Classic */
-    public static final String MIFARE_CLASSIC = "com.nxp.ndef.mifareclassic";
-    /**
-     * NDEF on iCODE SLI
-     * @hide
-     */
-    public static final String ICODE_SLI = "com.nxp.ndef.icodesli";
-
-    private final int mMaxNdefSize;
-    private final int mCardState;
-    private final NdefMessage mNdefMsg;
-    private final int mNdefType;
-
-    /**
-     * Get an instance of {@link Ndef} for the given tag.
-     *
-     * <p>Returns null if {@link Ndef} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag is not NDEF formatted, or that this tag
-     * is NDEF formatted but under a vendor specification that this Android
-     * device does not implement.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an NDEF compatible tag
-     * @return Ndef object
-     */
-    public static Ndef get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NDEF)) return null;
-        try {
-            return new Ndef(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Internal constructor, to be used by NfcAdapter
-     * @hide
-     */
-    public Ndef(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NDEF);
-        Bundle extras = tag.getTechExtras(TagTechnology.NDEF);
-        if (extras != null) {
-            mMaxNdefSize = extras.getInt(EXTRA_NDEF_MAXLENGTH);
-            mCardState = extras.getInt(EXTRA_NDEF_CARDSTATE);
-            mNdefMsg = extras.getParcelable(EXTRA_NDEF_MSG, android.nfc.NdefMessage.class);
-            mNdefType = extras.getInt(EXTRA_NDEF_TYPE);
-        } else {
-            throw new NullPointerException("NDEF tech extras are null.");
-        }
-
-    }
-
-    /**
-     * Get the {@link NdefMessage} that was read from the tag at discovery time.
-     *
-     * <p>If the NDEF Message is modified by an I/O operation then it
-     * will not be updated here, this function only returns what was discovered
-     * when the tag entered the field.
-     * <p>Note that this method may return null if the tag was in the
-     * INITIALIZED state as defined by NFC Forum, as in this state the
-     * tag is formatted to support NDEF but does not contain a message yet.
-     * <p>Does not cause any RF activity and does not block.
-     * @return NDEF Message read from the tag at discovery time, can be null
-     */
-    public NdefMessage getCachedNdefMessage() {
-        return mNdefMsg;
-    }
-
-    /**
-     * Get the NDEF tag type.
-     *
-     * <p>Returns one of {@link #NFC_FORUM_TYPE_1}, {@link #NFC_FORUM_TYPE_2},
-     * {@link #NFC_FORUM_TYPE_3}, {@link #NFC_FORUM_TYPE_4},
-     * {@link #MIFARE_CLASSIC} or another NDEF tag type that has not yet been
-     * formalized in this Android API.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return a string representing the NDEF tag type
-     */
-    public String getType() {
-        switch (mNdefType) {
-            case TYPE_1:
-                return NFC_FORUM_TYPE_1;
-            case TYPE_2:
-                return NFC_FORUM_TYPE_2;
-            case TYPE_3:
-                return NFC_FORUM_TYPE_3;
-            case TYPE_4:
-                return NFC_FORUM_TYPE_4;
-            case TYPE_MIFARE_CLASSIC:
-                return MIFARE_CLASSIC;
-            case TYPE_ICODE_SLI:
-                return ICODE_SLI;
-            default:
-                return UNKNOWN;
-        }
-    }
-
-    /**
-     * Get the maximum NDEF message size in bytes.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return size in bytes
-     */
-    public int getMaxSize() {
-        return mMaxNdefSize;
-    }
-
-    /**
-     * Determine if the tag is writable.
-     *
-     * <p>NFC Forum tags can be in read-only or read-write states.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * <p>Requires {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return true if the tag is writable
-     */
-    public boolean isWritable() {
-        return (mCardState == NDEF_MODE_READ_WRITE);
-    }
-
-    /**
-     * Read the current {@link android.nfc.NdefMessage} on this tag.
-     *
-     * <p>This always reads the current NDEF Message stored on the tag.
-     *
-     * <p>Note that this method may return null if the tag was in the
-     * INITIALIZED state as defined by NFC Forum, as in that state the
-     * tag is formatted to support NDEF but does not contain a message yet.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return the NDEF Message, can be null
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     * @throws FormatException if the NDEF Message on the tag is malformed
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public NdefMessage getNdefMessage() throws IOException, FormatException {
-        checkConnected();
-
-        try {
-            INfcTag tagService = mTag.getTagService();
-            if (tagService == null) {
-                throw new IOException("Mock tags don't support this operation.");
-            }
-            int serviceHandle = mTag.getServiceHandle();
-            if (tagService.isNdef(serviceHandle)) {
-                NdefMessage msg = tagService.ndefRead(serviceHandle);
-                if (msg == null && !tagService.isPresent(serviceHandle)) {
-                    throw new TagLostException();
-                }
-                return msg;
-            } else if (!tagService.isPresent(serviceHandle)) {
-                throw new TagLostException();
-            } else {
-                return null;
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return null;
-        }
-    }
-
-    /**
-     * Overwrite the {@link NdefMessage} on this tag.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param msg the NDEF Message to write, must not be null
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     * @throws FormatException if the NDEF Message to write is malformed
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
-        checkConnected();
-
-        try {
-            INfcTag tagService = mTag.getTagService();
-            if (tagService == null) {
-                throw new IOException("Mock tags don't support this operation.");
-            }
-            int serviceHandle = mTag.getServiceHandle();
-            if (tagService.isNdef(serviceHandle)) {
-                int errorCode = tagService.ndefWrite(serviceHandle, msg);
-                switch (errorCode) {
-                    case ErrorCodes.SUCCESS:
-                        break;
-                    case ErrorCodes.ERROR_IO:
-                        throw new IOException();
-                    case ErrorCodes.ERROR_INVALID_PARAM:
-                        throw new FormatException();
-                    default:
-                        // Should not happen
-                        throw new IOException();
-                }
-            }
-            else {
-                throw new IOException("Tag is not ndef");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-
-    /**
-     * Indicates whether a tag can be made read-only with {@link #makeReadOnly()}.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return true if it is possible to make this tag read-only
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public boolean canMakeReadOnly() {
-        INfcTag tagService = mTag.getTagService();
-        if (tagService == null) {
-            return false;
-        }
-        try {
-            return tagService.canMakeReadOnly(mNdefType);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return false;
-        }
-    }
-
-    /**
-     * Make a tag read-only.
-     *
-     * <p>This sets the CC field to indicate the tag is read-only,
-     * and where possible permanently sets the lock bits to prevent
-     * any further modification of the memory.
-     * <p>This is a one-way process and cannot be reverted!
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return true on success, false if it is not possible to make this tag read-only
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public boolean makeReadOnly() throws IOException {
-        checkConnected();
-
-        try {
-            INfcTag tagService = mTag.getTagService();
-            if (tagService == null) {
-                return false;
-            }
-            if (tagService.isNdef(mTag.getServiceHandle())) {
-                int errorCode = tagService.ndefMakeReadOnly(mTag.getServiceHandle());
-                switch (errorCode) {
-                    case ErrorCodes.SUCCESS:
-                        return true;
-                    case ErrorCodes.ERROR_IO:
-                        throw new IOException();
-                    case ErrorCodes.ERROR_INVALID_PARAM:
-                        return false;
-                    default:
-                        // Should not happen
-                        throw new IOException();
-                }
-           }
-           else {
-               throw new IOException("Tag is not ndef");
-           }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return false;
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/NdefFormatable.java b/nfc/java/android/nfc/tech/NdefFormatable.java
deleted file mode 100644
index 2240fe7..0000000
--- a/nfc/java/android/nfc/tech/NdefFormatable.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.FormatException;
-import android.nfc.INfcTag;
-import android.nfc.NdefMessage;
-import android.nfc.Tag;
-import android.nfc.TagLostException;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provide access to NDEF format operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NdefFormatable} object using {@link #get}.
- *
- * <p>Android devices with NFC must only enumerate and implement this
- * class for tags for which it can format to NDEF.
- *
- * <p>Unfortunately the procedures to convert unformated tags to NDEF formatted
- * tags are not specified by NFC Forum, and are not generally well-known. So
- * there is no mandatory set of tags for which all Android devices with NFC
- * must support {@link NdefFormatable}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NdefFormatable extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /**
-     * Get an instance of {@link NdefFormatable} for the given tag.
-     * <p>Does not cause any RF activity and does not block.
-     * <p>Returns null if {@link NdefFormatable} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag is not NDEF formatable by this Android device.
-     *
-     * @param tag an NDEF formatable tag
-     * @return NDEF formatable object
-     */
-    public static NdefFormatable get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NDEF_FORMATABLE)) return null;
-        try {
-            return new NdefFormatable(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Internal constructor, to be used by NfcAdapter
-     * @hide
-     */
-    public NdefFormatable(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NDEF_FORMATABLE);
-    }
-
-    /**
-     * Format a tag as NDEF, and write a {@link NdefMessage}.
-     *
-     * <p>This is a multi-step process, an IOException is thrown
-     * if any one step fails.
-     * <p>The card is left in a read-write state after this operation.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param firstMessage the NDEF message to write after formatting, can be null
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     * @throws FormatException if the NDEF Message to write is malformed
-     */
-    public void format(NdefMessage firstMessage) throws IOException, FormatException {
-        format(firstMessage, false);
-    }
-
-    /**
-     * Formats a tag as NDEF, write a {@link NdefMessage}, and make read-only.
-     *
-     * <p>This is a multi-step process, an IOException is thrown
-     * if any one step fails.
-     * <p>The card is left in a read-only state if this method returns successfully.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param firstMessage the NDEF message to write after formatting
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or the operation is canceled
-     * @throws FormatException if the NDEF Message to write is malformed
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void formatReadOnly(NdefMessage firstMessage) throws IOException, FormatException {
-        format(firstMessage, true);
-    }
-
-    /*package*/ void format(NdefMessage firstMessage, boolean makeReadOnly) throws IOException,
-            FormatException {
-        checkConnected();
-
-        try {
-            int serviceHandle = mTag.getServiceHandle();
-            INfcTag tagService = mTag.getTagService();
-            if (tagService == null) {
-                throw new IOException();
-            }
-            int errorCode = tagService.formatNdef(serviceHandle, MifareClassic.KEY_DEFAULT);
-            switch (errorCode) {
-                case ErrorCodes.SUCCESS:
-                    break;
-                case ErrorCodes.ERROR_IO:
-                    throw new IOException();
-                case ErrorCodes.ERROR_INVALID_PARAM:
-                    throw new FormatException();
-                default:
-                    // Should not happen
-                    throw new IOException();
-            }
-            // Now check and see if the format worked
-            if (!tagService.isNdef(serviceHandle)) {
-                throw new IOException();
-            }
-
-            // Write a message, if one was provided
-            if (firstMessage != null) {
-                errorCode = tagService.ndefWrite(serviceHandle, firstMessage);
-                switch (errorCode) {
-                    case ErrorCodes.SUCCESS:
-                        break;
-                    case ErrorCodes.ERROR_IO:
-                        throw new IOException();
-                    case ErrorCodes.ERROR_INVALID_PARAM:
-                        throw new FormatException();
-                    default:
-                        // Should not happen
-                        throw new IOException();
-                }
-            }
-
-            // optionally make read-only
-            if (makeReadOnly) {
-                errorCode = tagService.ndefMakeReadOnly(serviceHandle);
-                switch (errorCode) {
-                    case ErrorCodes.SUCCESS:
-                        break;
-                    case ErrorCodes.ERROR_IO:
-                        throw new IOException();
-                    case ErrorCodes.ERROR_INVALID_PARAM:
-                        throw new IOException();
-                    default:
-                        // Should not happen
-                        throw new IOException();
-                }
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/NfcA.java b/nfc/java/android/nfc/tech/NfcA.java
deleted file mode 100644
index 7e66483..0000000
--- a/nfc/java/android/nfc/tech/NfcA.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provides access to NFC-A (ISO 14443-3A) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NfcA} object using {@link #get}.
- * <p>The primary NFC-A I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NfcA extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /** @hide */
-    public static final String EXTRA_SAK = "sak";
-    /** @hide */
-    public static final String EXTRA_ATQA = "atqa";
-
-    private short mSak;
-    private byte[] mAtqa;
-
-    /**
-     * Get an instance of {@link NfcA} for the given tag.
-     * <p>Returns null if {@link NfcA} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag does not support NFC-A.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an NFC-A compatible tag
-     * @return NFC-A object
-     */
-    public static NfcA get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NFC_A)) return null;
-        try {
-            return new NfcA(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public NfcA(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NFC_A);
-        Bundle extras = tag.getTechExtras(TagTechnology.NFC_A);
-        mSak = extras.getShort(EXTRA_SAK);
-        mAtqa = extras.getByteArray(EXTRA_ATQA);
-    }
-
-    /**
-     * Return the ATQA/SENS_RES bytes from tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return ATQA/SENS_RES bytes
-     */
-    public byte[] getAtqa() {
-        return mAtqa;
-    }
-
-    /**
-     * Return the SAK/SEL_RES bytes from tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return SAK bytes
-     */
-    public short getSak() {
-        return mSak;
-    }
-
-    /**
-     * Send raw NFC-A commands to the tag and receive the response.
-     *
-     * <p>Applications must not append the EoD (CRC) to the payload,
-     * it will be automatically calculated.
-     * <p>Applications must only send commands that are complete bytes,
-     * for example a SENS_REQ is not possible (these are used to
-     * manage tag polling and initialization).
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param data bytes to send
-     * @return bytes received in response
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or this operation is canceled
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-
-    /**
-     * Set the {@link #transceive} timeout in milliseconds.
-     *
-     * <p>The timeout only applies to {@link #transceive} on this object,
-     * and is reset to a default value when {@link #close} is called.
-     *
-     * <p>Setting a longer timeout may be useful when performing
-     * transactions that require a long processing time on the tag
-     * such as key generation.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param timeout timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void setTimeout(int timeout) {
-        try {
-            int err = mTag.getTagService().setTimeout(TagTechnology.NFC_A, timeout);
-            if (err != ErrorCodes.SUCCESS) {
-                throw new IllegalArgumentException("The supplied timeout is not valid");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-
-    /**
-     * Get the current {@link #transceive} timeout in milliseconds.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public int getTimeout() {
-        try {
-            return mTag.getTagService().getTimeout(TagTechnology.NFC_A);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return 0;
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/NfcB.java b/nfc/java/android/nfc/tech/NfcB.java
deleted file mode 100644
index 3ebd47f..0000000
--- a/nfc/java/android/nfc/tech/NfcB.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc.tech;
-
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import java.io.IOException;
-
-/**
- * Provides access to NFC-B (ISO 14443-3B) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NfcB} object using {@link #get}.
- * <p>The primary NFC-B I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NfcB extends BasicTagTechnology {
-    /** @hide */
-    public static final String EXTRA_APPDATA = "appdata";
-    /** @hide */
-    public static final String EXTRA_PROTINFO = "protinfo";
-
-    private byte[] mAppData;
-    private byte[] mProtInfo;
-
-    /**
-     * Get an instance of {@link NfcB} for the given tag.
-     * <p>Returns null if {@link NfcB} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag does not support NFC-B.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an NFC-B compatible tag
-     * @return NFC-B object
-     */
-    public static NfcB get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NFC_B)) return null;
-        try {
-            return new NfcB(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public NfcB(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NFC_B);
-        Bundle extras = tag.getTechExtras(TagTechnology.NFC_B);
-        mAppData = extras.getByteArray(EXTRA_APPDATA);
-        mProtInfo = extras.getByteArray(EXTRA_PROTINFO);
-    }
-
-    /**
-     * Return the Application Data bytes from ATQB/SENSB_RES at tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return Application Data bytes from ATQB/SENSB_RES bytes
-     */
-    public byte[] getApplicationData() {
-        return mAppData;
-    }
-
-    /**
-     * Return the Protocol Info bytes from ATQB/SENSB_RES at tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return Protocol Info bytes from ATQB/SENSB_RES bytes
-     */
-    public byte[] getProtocolInfo() {
-        return mProtInfo;
-    }
-
-    /**
-     * Send raw NFC-B commands to the tag and receive the response.
-     *
-     * <p>Applications must not append the EoD (CRC) to the payload,
-     * it will be automatically calculated.
-     * <p>Applications must not send commands that manage the polling
-     * loop and initialization (SENSB_REQ, SLOT_MARKER etc).
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param data bytes to send
-     * @return bytes received in response
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or this operation is canceled
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-}
diff --git a/nfc/java/android/nfc/tech/NfcBarcode.java b/nfc/java/android/nfc/tech/NfcBarcode.java
deleted file mode 100644
index 421ba78..0000000
--- a/nfc/java/android/nfc/tech/NfcBarcode.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2012 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 android.nfc.tech;
-
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-/**
- * Provides access to tags containing just a barcode.
- *
- * <p>Acquire an {@link NfcBarcode} object using {@link #get}.
- *
- */
-public final class NfcBarcode extends BasicTagTechnology {
-
-    /** Kovio Tags */
-    public static final int TYPE_KOVIO = 1;
-    public static final int TYPE_UNKNOWN = -1;
-
-    /** @hide */
-    public static final String EXTRA_BARCODE_TYPE = "barcodetype";
-
-    private int mType;
-
-    /**
-     * Get an instance of {@link NfcBarcode} for the given tag.
-     *
-     * <p>Returns null if {@link NfcBarcode} was not enumerated in {@link Tag#getTechList}.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an NfcBarcode compatible tag
-     * @return NfcBarcode object
-     */
-    public static NfcBarcode get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NFC_BARCODE)) return null;
-        try {
-            return new NfcBarcode(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Internal constructor, to be used by NfcAdapter
-     * @hide
-     */
-    public NfcBarcode(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NFC_BARCODE);
-        Bundle extras = tag.getTechExtras(TagTechnology.NFC_BARCODE);
-        if (extras != null) {
-            mType = extras.getInt(EXTRA_BARCODE_TYPE);
-        } else {
-            throw new NullPointerException("NfcBarcode tech extras are null.");
-        }
-    }
-
-    /**
-     * Returns the NFC Barcode tag type.
-     *
-     * <p>Currently only one of {@link #TYPE_KOVIO} or {@link #TYPE_UNKNOWN}.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return the NFC Barcode tag type
-     */
-    public int getType() {
-        return mType;
-    }
-
-    /**
-     * Returns the barcode of an NfcBarcode tag.
-     *
-     * <p> Tags of {@link #TYPE_KOVIO} return 16 bytes:
-     *     <ul>
-     *     <p> The first byte is 0x80 ORd with a manufacturer ID, corresponding
-     *       to ISO/IEC 7816-6.
-     *     <p> The second byte describes the payload data format. Defined data
-     *       format types include the following:<ul>
-     *       <li>0x00: Reserved for manufacturer assignment</li>
-     *       <li>0x01: 96-bit URL with "http://www." prefix</li>
-     *       <li>0x02: 96-bit URL with "https://www." prefix</li>
-     *       <li>0x03: 96-bit URL with "http://" prefix</li>
-     *       <li>0x04: 96-bit URL with "https://" prefix</li>
-     *       <li>0x05: 96-bit GS1 EPC</li>
-     *       <li>0x06-0xFF: reserved</li>
-     *       </ul>
-     *     <p>The following 12 bytes are payload:<ul>
-     *       <li> In case of a URL payload, the payload is encoded in US-ASCII,
-     *            following the limitations defined in RFC3987.
-     *            {@see <a href="http://www.ietf.org/rfc/rfc3987.txt">RFC 3987</a>}</li>
-     *       <li> In case of GS1 EPC data, see <a href="http://www.gs1.org/gsmp/kc/epcglobal/tds/">
-     *            GS1 Electronic Product Code (EPC) Tag Data Standard (TDS)</a> for more details.
-     *       </li>
-     *     </ul>
-     *     <p>The last 2 bytes comprise the CRC.
-     *     </ul>
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return a byte array containing the barcode
-     * @see <a href="http://www.thinfilm.no/docs/thinfilm-nfc-barcode-datasheet.pdf">
-     *      Thinfilm NFC Barcode tag specification (previously Kovio NFC Barcode)</a>
-     * @see <a href="http://www.thinfilm.no/docs/thinfilm-nfc-barcode-data-format.pdf">
-     *      Thinfilm NFC Barcode data format (previously Kovio NFC Barcode)</a>
-     */
-    public byte[] getBarcode() {
-        switch (mType) {
-            case TYPE_KOVIO:
-                // For Kovio tags the barcode matches the ID
-                return mTag.getId();
-            default:
-                return null;
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/NfcF.java b/nfc/java/android/nfc/tech/NfcF.java
deleted file mode 100644
index 2ccd388..0000000
--- a/nfc/java/android/nfc/tech/NfcF.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provides access to NFC-F (JIS 6319-4) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NfcF} object using {@link #get}.
- * <p>The primary NFC-F I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NfcF extends BasicTagTechnology {
-    private static final String TAG = "NFC";
-
-    /** @hide */
-    public static final String EXTRA_SC = "systemcode";
-    /** @hide */
-    public static final String EXTRA_PMM = "pmm";
-
-    private byte[] mSystemCode = null;
-    private byte[] mManufacturer = null;
-
-    /**
-     * Get an instance of {@link NfcF} for the given tag.
-     * <p>Returns null if {@link NfcF} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag does not support NFC-F.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an NFC-F compatible tag
-     * @return NFC-F object
-     */
-    public static NfcF get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NFC_F)) return null;
-        try {
-            return new NfcF(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public NfcF(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NFC_F);
-        Bundle extras = tag.getTechExtras(TagTechnology.NFC_F);
-        if (extras != null) {
-            mSystemCode = extras.getByteArray(EXTRA_SC);
-            mManufacturer = extras.getByteArray(EXTRA_PMM);
-        }
-    }
-
-    /**
-     * Return the System Code bytes from tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return System Code bytes
-     */
-    public byte[] getSystemCode() {
-      return mSystemCode;
-    }
-
-    /**
-     * Return the Manufacturer bytes from tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return Manufacturer bytes
-     */
-    public byte[] getManufacturer() {
-      return mManufacturer;
-    }
-
-    /**
-     * Send raw NFC-F commands to the tag and receive the response.
-     *
-     * <p>Applications must not prefix the SoD (preamble and sync code)
-     * and/or append the EoD (CRC) to the payload, it will be automatically calculated.
-     *
-     * <p>A typical NFC-F frame for this method looks like:
-     * <pre>
-     * LENGTH (1 byte) --- CMD (1 byte) -- IDm (8 bytes) -- PARAMS (LENGTH - 10 bytes)
-     * </pre>
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param data bytes to send
-     * @return bytes received in response
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or this operation is canceled
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-
-    /**
-     * Set the {@link #transceive} timeout in milliseconds.
-     *
-     * <p>The timeout only applies to {@link #transceive} on this object,
-     * and is reset to a default value when {@link #close} is called.
-     *
-     * <p>Setting a longer timeout may be useful when performing
-     * transactions that require a long processing time on the tag
-     * such as key generation.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param timeout timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void setTimeout(int timeout) {
-        try {
-            int err = mTag.getTagService().setTimeout(TagTechnology.NFC_F, timeout);
-            if (err != ErrorCodes.SUCCESS) {
-                throw new IllegalArgumentException("The supplied timeout is not valid");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-        }
-    }
-
-    /**
-     * Get the current {@link #transceive} timeout in milliseconds.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @return timeout value in milliseconds
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public int getTimeout() {
-        try {
-            return mTag.getTagService().getTimeout(TagTechnology.NFC_F);
-        } catch (RemoteException e) {
-            Log.e(TAG, "NFC service dead", e);
-            return 0;
-        }
-    }
-}
diff --git a/nfc/java/android/nfc/tech/NfcV.java b/nfc/java/android/nfc/tech/NfcV.java
deleted file mode 100644
index 186c63b..0000000
--- a/nfc/java/android/nfc/tech/NfcV.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc.tech;
-
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import java.io.IOException;
-
-/**
- * Provides access to NFC-V (ISO 15693) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NfcV} object using {@link #get}.
- * <p>The primary NFC-V I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NfcV extends BasicTagTechnology {
-    /** @hide */
-    public static final String EXTRA_RESP_FLAGS = "respflags";
-
-    /** @hide */
-    public static final String EXTRA_DSFID = "dsfid";
-
-    private byte mRespFlags;
-    private byte mDsfId;
-
-    /**
-     * Get an instance of {@link NfcV} for the given tag.
-     * <p>Returns null if {@link NfcV} was not enumerated in {@link Tag#getTechList}.
-     * This indicates the tag does not support NFC-V.
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @param tag an NFC-V compatible tag
-     * @return NFC-V object
-     */
-    public static NfcV get(Tag tag) {
-        if (!tag.hasTech(TagTechnology.NFC_V)) return null;
-        try {
-            return new NfcV(tag);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    /** @hide */
-    public NfcV(Tag tag) throws RemoteException {
-        super(tag, TagTechnology.NFC_V);
-        Bundle extras = tag.getTechExtras(TagTechnology.NFC_V);
-        mRespFlags = extras.getByte(EXTRA_RESP_FLAGS);
-        mDsfId = extras.getByte(EXTRA_DSFID);
-    }
-
-    /**
-     * Return the Response Flag bytes from tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return Response Flag bytes
-     */
-    public byte getResponseFlags() {
-        return mRespFlags;
-    }
-
-    /**
-     * Return the DSF ID bytes from tag discovery.
-     *
-     * <p>Does not cause any RF activity and does not block.
-     *
-     * @return DSF ID bytes
-     */
-    public byte getDsfId() {
-        return mDsfId;
-    }
-
-    /**
-     * Send raw NFC-V commands to the tag and receive the response.
-     *
-     * <p>Applications must not append the CRC to the payload,
-     * it will be automatically calculated. The application does
-     * provide FLAGS, CMD and PARAMETER bytes.
-     *
-     * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes
-     * that can be sent with {@link #transceive}.
-     *
-     * <p>This is an I/O operation and will block until complete. It must
-     * not be called from the main application thread. A blocked call will be canceled with
-     * {@link IOException} if {@link #close} is called from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @param data bytes to send
-     * @return bytes received in response
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or this operation is canceled
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
-
-
-    /**
-     * Return the maximum number of bytes that can be sent with {@link #transceive}.
-     * @return the maximum number of bytes that can be sent with {@link #transceive}.
-     */
-    public int getMaxTransceiveLength() {
-        return getMaxTransceiveLengthInternal();
-    }
-}
diff --git a/nfc/java/android/nfc/tech/TagTechnology.java b/nfc/java/android/nfc/tech/TagTechnology.java
deleted file mode 100644
index 839fe42..0000000
--- a/nfc/java/android/nfc/tech/TagTechnology.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc.tech;
-
-import android.nfc.Tag;
-
-import java.io.Closeable;
-import java.io.IOException;
-
-/**
- * {@link TagTechnology} is an interface to a technology in a {@link Tag}.
- * <p>
- * Obtain a {@link TagTechnology} implementation by calling the static method <code>get()</code>
- * on the implementation class.
- * <p>
- * NFC tags are based on a number of independently developed technologies and offer a
- * wide range of capabilities. The
- * {@link TagTechnology} implementations provide access to these different
- * technologies and capabilities. Some sub-classes map to technology
- * specification (for example {@link NfcA}, {@link IsoDep}, others map to
- * pseudo-technologies or capabilities (for example {@link Ndef}, {@link NdefFormatable}).
- * <p>
- * It is mandatory for all Android NFC devices to provide the following
- * {@link TagTechnology} implementations.
- * <ul>
- * <li>{@link NfcA} (also known as ISO 14443-3A)
- * <li>{@link NfcB} (also known as ISO 14443-3B)
- * <li>{@link NfcF} (also known as JIS 6319-4)
- * <li>{@link NfcV} (also known as ISO 15693)
- * <li>{@link IsoDep}
- * <li>{@link Ndef} on NFC Forum Type 1, Type 2, Type 3 or Type 4 compliant tags
- * </ul>
- * It is optional for Android NFC devices to provide the following
- * {@link TagTechnology} implementations. If it is not provided, the
- * Android device will never enumerate that class via {@link Tag#getTechList}.
- * <ul>
- * <li>{@link MifareClassic}
- * <li>{@link MifareUltralight}
- * <li>{@link NfcBarcode}
- * <li>{@link NdefFormatable} must only be enumerated on tags for which this Android device
- * is capable of formatting. Proprietary knowledge is often required to format a tag
- * to make it NDEF compatible.
- * </ul>
- * <p>
- * {@link TagTechnology} implementations provide methods that fall into two classes:
- * <em>cached getters</em> and <em>I/O operations</em>.
- * <h4>Cached getters</h4>
- * These methods (usually prefixed by <code>get</code> or <code>is</code>) return
- * properties of the tag, as determined at discovery time. These methods will never
- * block or cause RF activity, and do not require {@link #connect} to have been called.
- * They also never update, for example if a property is changed by an I/O operation with a tag
- * then the cached getter will still return the result from tag discovery time.
- * <h4>I/O operations</h4>
- * I/O operations may require RF activity, and may block. They have the following semantics.
- * <ul>
- * <li>{@link #connect} must be called before using any other I/O operation.
- * <li>{@link #close} must be called after completing I/O operations with a
- * {@link TagTechnology}, and it will cancel all other blocked I/O operations on other threads
- * (including {@link #connect} with {@link IOException}.
- * <li>Only one {@link TagTechnology} can be connected at a time. Other calls to
- * {@link #connect} will return {@link IOException}.
- * <li>I/O operations may block, and should never be called on the main application
- * thread.
- * </ul>
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public interface TagTechnology extends Closeable {
-    /**
-     * This technology is an instance of {@link NfcA}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int NFC_A = 1;
-
-    /**
-     * This technology is an instance of {@link NfcB}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int NFC_B = 2;
-
-    /**
-     * This technology is an instance of {@link IsoDep}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int ISO_DEP = 3;
-
-    /**
-     * This technology is an instance of {@link NfcF}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int NFC_F = 4;
-
-    /**
-     * This technology is an instance of {@link NfcV}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int NFC_V = 5;
-
-    /**
-     * This technology is an instance of {@link Ndef}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int NDEF = 6;
-
-    /**
-     * This technology is an instance of {@link NdefFormatable}.
-     * <p>Support for this technology type is mandatory.
-     * @hide
-     */
-    public static final int NDEF_FORMATABLE = 7;
-
-    /**
-     * This technology is an instance of {@link MifareClassic}.
-     * <p>Support for this technology type is optional. If a stack doesn't support this technology
-     * type tags using it must still be discovered and present the lower level radio interface
-     * technologies in use.
-     * @hide
-     */
-    public static final int MIFARE_CLASSIC = 8;
-
-    /**
-     * This technology is an instance of {@link MifareUltralight}.
-     * <p>Support for this technology type is optional. If a stack doesn't support this technology
-     * type tags using it must still be discovered and present the lower level radio interface
-     * technologies in use.
-     * @hide
-     */
-    public static final int MIFARE_ULTRALIGHT = 9;
-
-    /**
-     * This technology is an instance of {@link NfcBarcode}.
-     * <p>Support for this technology type is optional. If a stack doesn't support this technology
-     * type tags using it must still be discovered and present the lower level radio interface
-     * technologies in use.
-     * @hide
-     */
-    public static final int NFC_BARCODE = 10;
-
-    /**
-     * Get the {@link Tag} object backing this {@link TagTechnology} object.
-     * @return the {@link Tag} backing this {@link TagTechnology} object.
-     */
-    public Tag getTag();
-
-    /**
-     * Enable I/O operations to the tag from this {@link TagTechnology} object.
-     * <p>May cause RF activity and may block. Must not be called
-     * from the main application thread. A blocked call will be canceled with
-     * {@link IOException} by calling {@link #close} from another thread.
-     * <p>Only one {@link TagTechnology} object can be connected to a {@link Tag} at a time.
-     * <p>Applications must call {@link #close} when I/O operations are complete.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @see #close()
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or connect is canceled
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void connect() throws IOException;
-
-    /**
-     * Re-connect to the {@link Tag} associated with this connection. Reconnecting to a tag can be
-     * used to reset the state of the tag itself.
-     *
-     * <p>May cause RF activity and may block. Must not be called
-     * from the main application thread. A blocked call will be canceled with
-     * {@link IOException} by calling {@link #close} from another thread.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @see #connect()
-     * @see #close()
-     * @throws TagLostException if the tag leaves the field
-     * @throws IOException if there is an I/O failure, or connect is canceled
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     * @hide
-     */
-    public void reconnect() throws IOException;
-
-    /**
-     * Disable I/O operations to the tag from this {@link TagTechnology} object, and release resources.
-     * <p>Also causes all blocked I/O operations on other thread to be canceled and
-     * return with {@link IOException}.
-     *
-     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
-     *
-     * @see #connect()
-     * @throws SecurityException if the tag object is reused after the tag has left the field
-     */
-    public void close() throws IOException;
-
-    /**
-     * Helper to indicate if I/O operations should be possible.
-     *
-     * <p>Returns true if {@link #connect} has completed, and {@link #close} has not been
-     * called, and the {@link Tag} is not known to be out of range.
-     * <p>Does not cause RF activity, and does not block.
-     *
-     * @return true if I/O operations should be possible
-     */
-    public boolean isConnected();
-}
diff --git a/nfc/java/android/nfc/tech/package.html b/nfc/java/android/nfc/tech/package.html
deleted file mode 100644
index a99828f..0000000
--- a/nfc/java/android/nfc/tech/package.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<HTML>
-<BODY>
-<p>
-These classes provide access to a tag technology's features, which vary by the type
-of tag that is scanned. A scanned tag can support multiple technologies, and you can find
-out what they are by calling {@link android.nfc.Tag#getTechList getTechList()}.</p>
-
-<p>For more information on dealing with tag technologies and handling the ones that you care about, see
-<a href="{@docRoot}guide/topics/nfc/index.html#dispatch">The Tag Dispatch System</a>.
-The {@link android.nfc.tech.TagTechnology} interface provides an overview of the
-supported technologies.</p>
-</BODY>
-</HTML>
diff --git a/nfc/lint-baseline.xml b/nfc/lint-baseline.xml
deleted file mode 100644
index 67b496e..0000000
--- a/nfc/lint-baseline.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01">
-
-    <issue
-        id="FlaggedApi"
-        message="Method `NfcOemExtension()` is a flagged API and should be inside an `if (Flags.nfcOemExtension())` check (or annotate the surrounding method `NfcAdapter` with `@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) to transfer requirement to caller`)"
-        errorLine1="        mNfcOemExtension = new NfcOemExtension(mContext, this);"
-        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
-            line="909"
-            column="28"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
-        message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
-        errorLine1="                &amp;&amp; ((pollTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH"
-        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
-            line="1917"
-            column="39"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
-        message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
-        errorLine1="                &amp;&amp; ((pollTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH"
-        errorLine2="                                                                ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
-            line="1917"
-            column="65"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
-        message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
-        errorLine1="                || (listenTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {"
-        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
-            line="1918"
-            column="40"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
-        message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
-        errorLine1="                || (listenTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {"
-        errorLine2="                                                                 ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
-            line="1918"
-            column="66"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
-        message="Method `onVendorNciResponse()` is a flagged API and should be inside an `if (Flags.nfcVendorCmd())` check (or annotate the surrounding method `onVendorResponseReceived` with `@FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD) to transfer requirement to caller`)"
-        errorLine1="                    executor.execute(() -> callback.onVendorNciResponse(gid, oid, payload));"
-        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcVendorNciCallbackListener.java"
-            line="88"
-            column="44"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
-        message="Method `onVendorNciNotification()` is a flagged API and should be inside an `if (Flags.nfcVendorCmd())` check (or annotate the surrounding method `onVendorNotificationReceived` with `@FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD) to transfer requirement to caller`)"
-        errorLine1="                    executor.execute(() -> callback.onVendorNciNotification(gid, oid, payload));"
-        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/NfcVendorNciCallbackListener.java"
-            line="106"
-            column="44"/>
-    </issue>
-
-</issues>
diff --git a/nfc/tests/Android.bp b/nfc/tests/Android.bp
deleted file mode 100644
index 17fb810..0000000
--- a/nfc/tests/Android.bp
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    default_team: "trendy_team_fwk_nfc",
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_test {
-    name: "NfcManagerTests",
-    static_libs: [
-        "androidx.test.core",
-        "androidx.test.rules",
-        "androidx.test.runner",
-        "androidx.test.ext.junit",
-        "mockito-target-extended-minus-junit4",
-        "frameworks-base-testutils",
-        "truth",
-        "androidx.annotation_annotation",
-        "androidx.appcompat_appcompat",
-        "flag-junit",
-        "platform-test-annotations",
-        "testables",
-    ],
-    libs: [
-        "androidx.annotation_annotation",
-        "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
-        "framework-permission-s.stubs.module_lib",
-        "framework-permission.stubs.module_lib",
-        "android.test.base.stubs.system",
-        "android.test.mock.stubs.system",
-        "android.test.runner.stubs.system",
-        "framework-nfc.impl",
-    ],
-    jni_libs: [
-        // Required for ExtendedMockito
-        "libdexmakerjvmtiagent",
-        "libstaticjvmtiagent",
-    ],
-    srcs: [
-        "src/**/*.java",
-        ":framework-nfc-updatable-sources",
-        ":framework-nfc-non-updatable-sources",
-    ],
-    platform_apis: true,
-    certificate: "platform",
-    test_suites: [
-        "device-tests",
-        "mts-nfc",
-    ],
-    min_sdk_version: "35", // Should be 36 later.
-}
diff --git a/nfc/tests/AndroidManifest.xml b/nfc/tests/AndroidManifest.xml
deleted file mode 100644
index 9564672..0000000
--- a/nfc/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.nfc">
-
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <!-- This is a self-instrumenting test package. -->
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.nfc"
-                     android:label="NFC Manager Tests">
-    </instrumentation>
-
-</manifest>
-
diff --git a/nfc/tests/AndroidTest.xml b/nfc/tests/AndroidTest.xml
deleted file mode 100644
index 490d6f5..0000000
--- a/nfc/tests/AndroidTest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Config for NFC Manager test cases">
-    <option name="test-suite-tag" value="apct"/>
-    <option name="test-suite-tag" value="apct-instrumentation"/>
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="NfcManagerTests.apk" />
-    </target_preparer>
-
-    <option name="test-suite-tag" value="apct"/>
-    <option name="test-tag" value="NfcManagerTests"/>
-
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.nfc" />
-        <option name="hidden-api-checks" value="false"/>
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
-    </test>
-</configuration>
diff --git a/nfc/tests/src/android/nfc/NdefMessageTest.java b/nfc/tests/src/android/nfc/NdefMessageTest.java
deleted file mode 100644
index 9ca295d..0000000
--- a/nfc/tests/src/android/nfc/NdefMessageTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class NdefMessageTest {
-    private NdefMessage mNdefMessage;
-    private NdefRecord mNdefRecord;
-
-    @Before
-    public void setUp() {
-        mNdefRecord = NdefRecord.createUri("http://www.example.com");
-        mNdefMessage = new NdefMessage(mNdefRecord);
-    }
-
-    @After
-    public void tearDown() {
-    }
-
-    @Test
-    public void testGetRecords() {
-        NdefRecord[] records = mNdefMessage.getRecords();
-        assertThat(records).isNotNull();
-        assertThat(records).hasLength(1);
-        assertThat(records[0]).isEqualTo(mNdefRecord);
-    }
-
-    @Test
-    public void testToByteArray() throws FormatException {
-        byte[] bytes = mNdefMessage.toByteArray();
-        assertThat(bytes).isNotNull();
-        assertThat(bytes.length).isGreaterThan(0);
-        NdefMessage ndefMessage = new NdefMessage(bytes);
-        assertThat(ndefMessage).isNotNull();
-    }
-}
diff --git a/nfc/tests/src/android/nfc/NdefRecordTest.java b/nfc/tests/src/android/nfc/NdefRecordTest.java
deleted file mode 100644
index 044c674..0000000
--- a/nfc/tests/src/android/nfc/NdefRecordTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Locale;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class NdefRecordTest {
-
-    @Test
-    public void testNdefRecordConstructor() throws FormatException {
-        NdefRecord applicationRecord = NdefRecord
-                .createApplicationRecord("com.android.test");
-        NdefRecord ndefRecord = new NdefRecord(applicationRecord.toByteArray());
-        assertThat(ndefRecord).isNotNull();
-        assertThat(ndefRecord.toByteArray().length).isGreaterThan(0);
-        assertThat(ndefRecord.getType()).isEqualTo("android.com:pkg".getBytes());
-        assertThat(ndefRecord.getPayload()).isEqualTo("com.android.test".getBytes());
-    }
-
-    @Test
-    public void testCreateExternal() {
-        NdefRecord ndefRecord = NdefRecord.createExternal("test",
-                "android.com:pkg", "com.android.test".getBytes());
-        assertThat(ndefRecord).isNotNull();
-        assertThat(ndefRecord.getType()).isEqualTo("test:android.com:pkg".getBytes());
-        assertThat(ndefRecord.getPayload()).isEqualTo("com.android.test".getBytes());
-    }
-
-    @Test
-    public void testCreateUri() {
-        NdefRecord ndefRecord = NdefRecord.createUri("http://www.example.com");
-        assertThat(ndefRecord).isNotNull();
-        assertThat(ndefRecord.getTnf()).isEqualTo(NdefRecord.TNF_WELL_KNOWN);
-        assertThat(ndefRecord.getType()).isEqualTo(NdefRecord.RTD_URI);
-    }
-
-    @Test
-    public void testCreateMime() {
-        NdefRecord ndefRecord = NdefRecord.createMime("text/plain", "example".getBytes());
-        assertThat(ndefRecord).isNotNull();
-        assertThat(ndefRecord.getTnf()).isEqualTo(NdefRecord.TNF_MIME_MEDIA);
-    }
-
-    @Test
-    public void testCreateTextRecord() {
-        String languageCode = Locale.getDefault().getLanguage();
-        NdefRecord ndefRecord = NdefRecord.createTextRecord(languageCode, "testdata");
-        assertThat(ndefRecord).isNotNull();
-        assertThat(ndefRecord.getTnf()).isEqualTo(NdefRecord.TNF_WELL_KNOWN);
-        assertThat(ndefRecord.getType()).isEqualTo(NdefRecord.RTD_TEXT);
-    }
-
-}
diff --git a/nfc/tests/src/android/nfc/NfcAntennaInfoTest.java b/nfc/tests/src/android/nfc/NfcAntennaInfoTest.java
deleted file mode 100644
index c24816d..0000000
--- a/nfc/tests/src/android/nfc/NfcAntennaInfoTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class NfcAntennaInfoTest {
-    private NfcAntennaInfo mNfcAntennaInfo;
-
-
-    @Before
-    public void setUp() {
-        AvailableNfcAntenna availableNfcAntenna = mock(AvailableNfcAntenna.class);
-        List<AvailableNfcAntenna> antennas = new ArrayList<>();
-        antennas.add(availableNfcAntenna);
-        mNfcAntennaInfo = new NfcAntennaInfo(1, 1, false, antennas);
-    }
-
-    @After
-    public void tearDown() {
-    }
-
-    @Test
-    public void testGetDeviceHeight() {
-        int height = mNfcAntennaInfo.getDeviceHeight();
-        assertThat(height).isEqualTo(1);
-    }
-
-    @Test
-    public void testGetDeviceWidth() {
-        int width = mNfcAntennaInfo.getDeviceWidth();
-        assertThat(width).isEqualTo(1);
-    }
-
-    @Test
-    public void testIsDeviceFoldable() {
-        boolean foldable = mNfcAntennaInfo.isDeviceFoldable();
-        assertThat(foldable).isFalse();
-    }
-
-    @Test
-    public void testGetAvailableNfcAntennas() {
-        List<AvailableNfcAntenna> antennas = mNfcAntennaInfo.getAvailableNfcAntennas();
-        assertThat(antennas).isNotNull();
-        assertThat(antennas.size()).isEqualTo(1);
-    }
-
-}
diff --git a/nfc/tests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java b/nfc/tests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
deleted file mode 100644
index 48f4288..0000000
--- a/nfc/tests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.nfc.NfcAdapter.ControllerAlwaysOnListener;
-import android.os.RemoteException;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * Test of {@link NfcControllerAlwaysOnListener}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class NfcControllerAlwaysOnListenerTest {
-
-    private INfcAdapter mNfcAdapter = mock(INfcAdapter.class);
-
-    private Throwable mThrowRemoteException = new RemoteException("RemoteException");
-
-    private static Executor getExecutor() {
-        return new Executor() {
-            @Override
-            public void execute(Runnable command) {
-                command.run();
-            }
-        };
-    }
-
-    private static void verifyListenerInvoked(ControllerAlwaysOnListener listener) {
-        verify(listener, times(1)).onControllerAlwaysOnChanged(anyBoolean());
-    }
-
-    @Test
-    public void testRegister_RegisterUnregisterWhenNotSupported() throws RemoteException {
-        // isControllerAlwaysOnSupported() returns false, not supported.
-        doReturn(false).when(mNfcAdapter).isControllerAlwaysOnSupported();
-        NfcControllerAlwaysOnListener mListener =
-                new NfcControllerAlwaysOnListener(mNfcAdapter);
-        ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
-        ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
-
-        // Verify that the state listener will not registered with the NFC Adapter
-        mListener.register(getExecutor(), mockListener1);
-        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
-
-        // Register a second client and no any call to NFC Adapter
-        mListener.register(getExecutor(), mockListener2);
-        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
-
-        // Unregister first listener, and no any call to NFC Adapter
-        mListener.unregister(mockListener1);
-        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
-        verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
-
-        // Unregister second listener, and no any call to NFC Adapter
-        mListener.unregister(mockListener2);
-        verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
-        verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
-    }
-
-    @Test
-    public void testRegister_RegisterUnregister() throws RemoteException {
-        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
-        NfcControllerAlwaysOnListener mListener =
-                new NfcControllerAlwaysOnListener(mNfcAdapter);
-        ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
-        ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
-
-        // Verify that the state listener registered with the NFC Adapter
-        mListener.register(getExecutor(), mockListener1);
-        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-
-        // Register a second client and no new call to NFC Adapter
-        mListener.register(getExecutor(), mockListener2);
-        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-
-        // Unregister first listener
-        mListener.unregister(mockListener1);
-        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-        verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
-
-        // Unregister second listener and the state listener registered with the NFC Adapter
-        mListener.unregister(mockListener2);
-        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-        verify(mNfcAdapter, times(1)).unregisterControllerAlwaysOnListener(any());
-    }
-
-    @Test
-    public void testRegister_FirstRegisterFails() throws RemoteException {
-        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
-        NfcControllerAlwaysOnListener mListener =
-                new NfcControllerAlwaysOnListener(mNfcAdapter);
-        ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
-        ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
-
-        // Throw a remote exception whenever first registering
-        doThrow(mThrowRemoteException).when(mNfcAdapter).registerControllerAlwaysOnListener(
-                any());
-
-        mListener.register(getExecutor(), mockListener1);
-        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-
-        // No longer throw an exception, instead succeed
-        doNothing().when(mNfcAdapter).registerControllerAlwaysOnListener(any());
-
-        // Register a different listener
-        mListener.register(getExecutor(), mockListener2);
-        verify(mNfcAdapter, times(2)).registerControllerAlwaysOnListener(any());
-
-        // Ensure first and second listener were invoked
-        mListener.onControllerAlwaysOnChanged(true);
-        verifyListenerInvoked(mockListener1);
-        verifyListenerInvoked(mockListener2);
-    }
-
-    @Test
-    public void testRegister_RegisterSameListenerTwice() throws RemoteException {
-        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
-        NfcControllerAlwaysOnListener mListener =
-                new NfcControllerAlwaysOnListener(mNfcAdapter);
-        ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
-
-        // Register the same listener Twice
-        mListener.register(getExecutor(), mockListener);
-        mListener.register(getExecutor(), mockListener);
-        verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-
-        // Invoke a state change and ensure the listener is only called once
-        mListener.onControllerAlwaysOnChanged(true);
-        verifyListenerInvoked(mockListener);
-    }
-
-    @Test
-    public void testNotify_AllListenersNotified() throws RemoteException {
-        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
-        NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter);
-        List<ControllerAlwaysOnListener> mockListeners = new ArrayList<>();
-        for (int i = 0; i < 10; i++) {
-            ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
-            listener.register(getExecutor(), mockListener);
-            mockListeners.add(mockListener);
-        }
-
-        // Invoke a state change and ensure all listeners are invoked
-        listener.onControllerAlwaysOnChanged(true);
-        for (ControllerAlwaysOnListener mListener : mockListeners) {
-            verifyListenerInvoked(mListener);
-        }
-    }
-
-    @Test
-    public void testStateChange_CorrectValue() throws RemoteException {
-        doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
-        runStateChangeValue(true, true);
-        runStateChangeValue(false, false);
-
-    }
-
-    private void runStateChangeValue(boolean isEnabledIn, boolean isEnabledOut) {
-        NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter);
-        ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
-        listener.register(getExecutor(), mockListener);
-        listener.onControllerAlwaysOnChanged(isEnabledIn);
-        verify(mockListener, times(1)).onControllerAlwaysOnChanged(isEnabledOut);
-        verify(mockListener, times(0)).onControllerAlwaysOnChanged(!isEnabledOut);
-    }
-}
diff --git a/nfc/tests/src/android/nfc/NfcManagerTest.java b/nfc/tests/src/android/nfc/NfcManagerTest.java
deleted file mode 100644
index 06314cc..0000000
--- a/nfc/tests/src/android/nfc/NfcManagerTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.dx.mockito.inline.extended.ExtendedMockito;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
-
-@RunWith(AndroidJUnit4.class)
-public class NfcManagerTest {
-
-    private MockitoSession mMockitoSession;
-    private NfcManager mNfcManager;
-    @Mock
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        mMockitoSession = ExtendedMockito.mockitoSession()
-                .mockStatic(NfcAdapter.class)
-                .strictness(Strictness.LENIENT)
-                .startMocking();
-        MockitoAnnotations.initMocks(this);
-
-        when(NfcAdapter.getNfcAdapter(any())).thenReturn(mock(NfcAdapter.class));
-        when(mContext.getApplicationContext()).thenReturn(mContext);
-        mNfcManager = new NfcManager(mContext);
-    }
-
-    @After
-    public void tearDown() {
-        mMockitoSession.finishMocking();
-    }
-
-    @Test
-    public void testGetDefaultAdapter() {
-        NfcAdapter nfcAdapter = mNfcManager.getDefaultAdapter();
-        assertThat(nfcAdapter).isNotNull();
-    }
-}
diff --git a/nfc/tests/src/android/nfc/NfcRoutingTableEntryTest.java b/nfc/tests/src/android/nfc/NfcRoutingTableEntryTest.java
deleted file mode 100644
index a90a716..0000000
--- a/nfc/tests/src/android/nfc/NfcRoutingTableEntryTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public final class NfcRoutingTableEntryTest {
-
-    @Test
-    public void testAidEntry_GetAid() {
-        String expectedAid = "A00000061A02";
-        RoutingTableAidEntry entry = new RoutingTableAidEntry(1, expectedAid, 0);
-
-        assertEquals(expectedAid, entry.getAid());
-    }
-
-    @Test
-    public void testProtocolEntry_GetProtocol() {
-        RoutingTableProtocolEntry entry =
-                new RoutingTableProtocolEntry(1, RoutingTableProtocolEntry.PROTOCOL_T1T, 0);
-
-        assertEquals(RoutingTableProtocolEntry.PROTOCOL_T1T, entry.getProtocol());
-    }
-
-    @Test
-    public void testSystemCodeEntry_GetSystemCode() {
-        byte[] expectedSystemCode = {0x01, 0x02, 0x03};
-        RoutingTableSystemCodeEntry entry =
-                new RoutingTableSystemCodeEntry(1, expectedSystemCode, 0);
-
-        assertArrayEquals(expectedSystemCode, entry.getSystemCode());
-    }
-
-    @Test
-    public void testTechnologyEntry_GetTechnology_A() {
-        RoutingTableTechnologyEntry entry =
-                new RoutingTableTechnologyEntry(1, RoutingTableTechnologyEntry.TECHNOLOGY_A, 0);
-
-        assertEquals(RoutingTableTechnologyEntry.TECHNOLOGY_A, entry.getTechnology());
-    }
-}
diff --git a/nfc/tests/src/android/nfc/OemLogItemsTest.java b/nfc/tests/src/android/nfc/OemLogItemsTest.java
deleted file mode 100644
index 21ef804..0000000
--- a/nfc/tests/src/android/nfc/OemLogItemsTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.time.Instant;
-
-@RunWith(JUnit4.class)
-public final class OemLogItemsTest {
-
-    @Test
-    public void testGetAction() {
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED)
-                .build();
-        assertEquals(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED, item.getAction());
-    }
-
-    @Test
-    public void testGetEvent() {
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_NFC_TOGGLE)
-                .setCallingEvent(OemLogItems.EVENT_ENABLE)
-                .build();
-        assertEquals(OemLogItems.EVENT_ENABLE, item.getEvent());
-    }
-
-    @Test
-    public void testGetCallingPid() {
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_NFC_TOGGLE)
-                .setCallingPid(1234)
-                .build();
-        assertEquals(1234, item.getCallingPid());
-    }
-
-    @Test
-    public void testGetCommandApdu() {
-        byte[] commandApdu = {0x01, 0x02, 0x03};
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_HCE_DATA)
-                .setApduCommand(commandApdu)
-                .build();
-        assertArrayEquals(commandApdu, item.getCommandApdu());
-    }
-
-    @Test
-    public void testGetResponseApdu() {
-        byte[] responseApdu = {0x04, 0x05, 0x06};
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_HCE_DATA)
-                .setApduResponse(responseApdu)
-                .build();
-        assertArrayEquals(responseApdu, item.getResponseApdu());
-    }
-
-    @Test
-    public void testGetRfFieldEventTimeMillis() {
-        Instant expectedTime = Instant.ofEpochSecond(1688768000, 123456789);
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED)
-                .setRfFieldOnTime(expectedTime)
-                .build();
-        assertEquals(expectedTime, item.getRfFieldEventTimeMillis());
-    }
-
-    @Test
-    public void testGetTag() {
-        Tag mockTag = mock(Tag.class);
-        OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_TAG_DETECTED)
-                .setTag(mockTag)
-                .build();
-        assertEquals(mockTag, item.getTag());
-    }
-}
diff --git a/nfc/tests/src/android/nfc/TechListParcelTest.java b/nfc/tests/src/android/nfc/TechListParcelTest.java
deleted file mode 100644
index a12bbbc..0000000
--- a/nfc/tests/src/android/nfc/TechListParcelTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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 android.nfc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Parcel;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-
-@RunWith(AndroidJUnit4.class)
-public class TechListParcelTest {
-
-    private static final String[] TECH_LIST_1 = new String[] { "tech1.1", "tech1.2" };
-    private static final String[] TECH_LIST_2 = new String[] { "tech2.1" };
-    private static final String[] TECH_LIST_EMPTY = new String[] {};
-
-    @Test
-    public void testWriteParcel() {
-        TechListParcel techListParcel = new TechListParcel(TECH_LIST_1, TECH_LIST_2);
-
-        Parcel parcel = Parcel.obtain();
-        techListParcel.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        TechListParcel actualTechList =
-                TechListParcel.CREATOR.createFromParcel(parcel);
-        parcel.recycle();
-
-        assertThat(actualTechList.getTechLists().length).isEqualTo(2);
-        assertThat(Arrays.equals(actualTechList.getTechLists()[0], TECH_LIST_1)).isTrue();
-        assertThat(Arrays.equals(actualTechList.getTechLists()[1], TECH_LIST_2)).isTrue();
-    }
-
-    @Test
-    public void testWriteParcelArrayEmpty() {
-        TechListParcel techListParcel = new TechListParcel();
-
-        Parcel parcel = Parcel.obtain();
-        techListParcel.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        TechListParcel actualTechList =
-                TechListParcel.CREATOR.createFromParcel(parcel);
-        parcel.recycle();
-
-        assertThat(actualTechList.getTechLists().length).isEqualTo(0);
-    }
-
-    @Test
-    public void testWriteParcelElementEmpty() {
-        TechListParcel techListParcel = new TechListParcel(TECH_LIST_EMPTY);
-
-        Parcel parcel = Parcel.obtain();
-        techListParcel.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        TechListParcel actualTechList =
-                TechListParcel.CREATOR.createFromParcel(parcel);
-        parcel.recycle();
-
-        assertThat(actualTechList.getTechLists().length).isEqualTo(1);
-        assertThat(Arrays.equals(actualTechList.getTechLists()[0], TECH_LIST_EMPTY)).isTrue();
-    }
-
-}
diff --git a/nfc/tests/src/android/nfc/cardemulation/AidGroupTest.java b/nfc/tests/src/android/nfc/cardemulation/AidGroupTest.java
deleted file mode 100644
index 7e00102..0000000
--- a/nfc/tests/src/android/nfc/cardemulation/AidGroupTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc.cardemulation;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.os.Parcel;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class AidGroupTest {
-    private AidGroup mAidGroup;
-
-    @Before
-    public void setUp() {
-        List<String> aids = new ArrayList<>();
-        aids.add("A0000000031010");
-        aids.add("A0000000041010");
-        aids.add("A0000000034710");
-        aids.add("A000000300");
-        mAidGroup = new AidGroup(aids, "payment");
-    }
-
-    @After
-    public void tearDown() {
-    }
-
-    @Test
-    public void testGetCategory() {
-        String category = mAidGroup.getCategory();
-        assertThat(category).isNotNull();
-        assertThat(category).isEqualTo("payment");
-    }
-
-    @Test
-    public void testGetAids() {
-        List<String> aids = mAidGroup.getAids();
-        assertThat(aids).isNotNull();
-        assertThat(aids.size()).isGreaterThan(0);
-        assertThat(aids.get(0)).isEqualTo("A0000000031010");
-    }
-
-    @Test
-    public void testWriteAsXml() throws IOException {
-        XmlSerializer out = mock(XmlSerializer.class);
-        mAidGroup.writeAsXml(out);
-        verify(out, atLeastOnce()).startTag(isNull(), anyString());
-        verify(out, atLeastOnce()).attribute(isNull(), anyString(), anyString());
-        verify(out, atLeastOnce()).endTag(isNull(), anyString());
-    }
-
-    @Test
-    public void testRightToParcel() {
-        Parcel parcel = mock(Parcel.class);
-        mAidGroup.writeToParcel(parcel, 0);
-        verify(parcel).writeString8(anyString());
-        verify(parcel).writeInt(anyInt());
-        verify(parcel).writeStringList(any());
-    }
-}
diff --git a/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java b/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java
deleted file mode 100644
index a215835..0000000
--- a/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc.cardemulation;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.role.RoleManager;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.nfc.Constants;
-import android.nfc.INfcCardEmulation;
-import android.nfc.NfcAdapter;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.dx.mockito.inline.extended.ExtendedMockito;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
-
-@RunWith(AndroidJUnit4.class)
-public class CardemulationTest {
-
-    private CardEmulation mCardEmulation;
-    @Mock
-    private Context mContext;
-    @Mock
-    private INfcCardEmulation mINfcCardEmulation;
-    @Mock
-    private NfcAdapter mNfcAdapter;
-    @Mock
-    private PackageManager mPackageManager;
-    private MockitoSession mMockitoSession;
-
-    @Before
-    public void setUp() {
-        mMockitoSession = ExtendedMockito.mockitoSession()
-                .mockStatic(NfcAdapter.class)
-                .mockStatic(Settings.Secure.class)
-                .strictness(Strictness.LENIENT)
-                .startMocking();
-        MockitoAnnotations.initMocks(this);
-
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION))
-                .thenReturn(true);
-        when(mContext.getApplicationContext()).thenReturn(mContext);
-        when(mContext.getPackageManager()).thenReturn(mPackageManager);
-        assertThat(mNfcAdapter).isNotNull();
-        when(mNfcAdapter.getCardEmulationService()).thenReturn(mINfcCardEmulation);
-        when(mNfcAdapter.getContext()).thenReturn(mContext);
-        mCardEmulation = CardEmulation.getInstance(mNfcAdapter);
-    }
-
-    @After
-    public void tearDown() {
-        mMockitoSession.finishMocking();
-    }
-
-    @Test
-    public void testIsDefaultServiceForCategory() throws RemoteException {
-        ComponentName componentName = mock(ComponentName.class);
-        UserHandle userHandle = mock(UserHandle.class);
-        when(userHandle.getIdentifier()).thenReturn(1);
-        when(mContext.getUser()).thenReturn(userHandle);
-        when(mINfcCardEmulation.isDefaultServiceForCategory(1, componentName,
-                "payment")).thenReturn(true);
-        boolean result = mCardEmulation.isDefaultServiceForCategory(componentName,
-                "payment");
-        assertThat(result).isTrue();
-        verify(mINfcCardEmulation).isDefaultServiceForCategory(1, componentName,
-                "payment");
-
-    }
-
-    @Test
-    public void testIsDefaultServiceForAid() throws RemoteException {
-        ComponentName componentName = mock(ComponentName.class);
-        UserHandle userHandle = mock(UserHandle.class);
-        when(userHandle.getIdentifier()).thenReturn(1);
-        when(mContext.getUser()).thenReturn(userHandle);
-        when(mINfcCardEmulation.isDefaultServiceForAid(1, componentName,
-                "payment")).thenReturn(true);
-        boolean result = mCardEmulation.isDefaultServiceForAid(componentName,
-                "payment");
-        assertThat(result).isTrue();
-        verify(mINfcCardEmulation).isDefaultServiceForAid(1, componentName,
-                "payment");
-    }
-
-    @Test
-    public void testCategoryAllowsForegroundPreference() throws Settings.SettingNotFoundException {
-        when(mContext.createContextAsUser(any(), anyInt())).thenReturn(mContext);
-        RoleManager roleManager = mock(RoleManager.class);
-        when(roleManager.isRoleAvailable(RoleManager.ROLE_WALLET)).thenReturn(false);
-        when(mContext.getSystemService(RoleManager.class)).thenReturn(roleManager);
-        ContentResolver contentResolver = mock(ContentResolver.class);
-        when(mContext.getContentResolver()).thenReturn(contentResolver);
-        when(Settings.Secure.getInt(contentResolver, Constants
-                .SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND)).thenReturn(1);
-        boolean result = mCardEmulation.categoryAllowsForegroundPreference("payment");
-        assertThat(result).isTrue();
-    }
-
-    @Test
-    public void testGetSelectionModeForCategory() throws RemoteException {
-        when(mINfcCardEmulation.isDefaultPaymentRegistered()).thenReturn(true);
-        int result = mCardEmulation.getSelectionModeForCategory("payment");
-        assertThat(result).isEqualTo(0);
-    }
-
-    @Test
-    public void testSetShouldDefaultToObserveModeForService() throws RemoteException {
-        UserHandle userHandle = mock(UserHandle.class);
-        when(userHandle.getIdentifier()).thenReturn(1);
-        when(mContext.getUser()).thenReturn(userHandle);
-        ComponentName componentName = mock(ComponentName.class);
-        when(mINfcCardEmulation.setShouldDefaultToObserveModeForService(1, componentName, true))
-                .thenReturn(true);
-        boolean result = mCardEmulation
-                .setShouldDefaultToObserveModeForService(componentName, true);
-        assertThat(result).isTrue();
-        verify(mINfcCardEmulation).setShouldDefaultToObserveModeForService(1, componentName, true);
-    }
-
-    @Test
-    public void testRegisterPollingLoopFilterForService()throws RemoteException {
-        UserHandle userHandle = mock(UserHandle.class);
-        when(userHandle.getIdentifier()).thenReturn(1);
-        when(mContext.getUser()).thenReturn(userHandle);
-        ComponentName componentName = mock(ComponentName.class);
-        when(mINfcCardEmulation.registerPollingLoopFilterForService(anyInt(),
-                any(), anyString(), anyBoolean())).thenReturn(true);
-        boolean result = mCardEmulation.registerPollingLoopFilterForService(componentName,
-                "A0000000041010", true);
-        assertThat(result).isTrue();
-        verify(mINfcCardEmulation)
-                .registerPollingLoopFilterForService(anyInt(), any(), anyString(), anyBoolean());
-    }
-
-    @Test
-    public void testRemovePollingLoopFilterForService()throws RemoteException {
-        UserHandle userHandle = mock(UserHandle.class);
-        when(userHandle.getIdentifier()).thenReturn(1);
-        when(mContext.getUser()).thenReturn(userHandle);
-        ComponentName componentName = mock(ComponentName.class);
-        when(mINfcCardEmulation.removePollingLoopFilterForService(anyInt(), any(), anyString()))
-                .thenReturn(true);
-        boolean result = mCardEmulation
-                .removePollingLoopFilterForService(componentName, "A0000000041010");
-        assertThat(result).isTrue();
-        verify(mINfcCardEmulation).removePollingLoopFilterForService(anyInt(), any(), anyString());
-    }
-}
diff --git a/nfc/tests/src/android/nfc/dta/NfcDtaTest.java b/nfc/tests/src/android/nfc/dta/NfcDtaTest.java
deleted file mode 100644
index 38fb7ef..0000000
--- a/nfc/tests/src/android/nfc/dta/NfcDtaTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2017 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 android.nfc.dta;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.nfc.INfcDta;
-import android.nfc.NfcAdapter;
-import android.os.RemoteException;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-public class NfcDtaTest {
-    private final String mServiceName = "serviceName";
-    private final int mServiceSap = 1;
-    private final int mMiu = 1;
-    private final int mRwSize = 1;
-    private final int mTestCaseId = 1;
-    @Mock
-    private NfcAdapter mMockNfcAdapter;
-    @Mock
-    private INfcDta mMockService;
-    @Mock
-    private Context mMockContext;
-
-    private NfcDta mNfcDta;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        when(mMockNfcAdapter.getContext()).thenReturn(mMockContext);
-        when(mMockNfcAdapter.getNfcDtaInterface()).thenReturn(mMockService);
-
-        mNfcDta = NfcDta.getInstance(mMockNfcAdapter);
-    }
-
-    @Test
-    public void testEnableData() throws RemoteException {
-        assertTrue(mNfcDta.enableDta());
-        verify(mMockService).enableDta();
-    }
-
-    @Test
-    public void testEnableDataWithRemoteException() throws RemoteException {
-        doThrow(new RemoteException()).when(mMockService).enableDta();
-
-        assertFalse(mNfcDta.enableDta());
-        verify(mMockService).enableDta();
-    }
-
-    @Test
-    public void testDisableData() throws RemoteException {
-        assertTrue(mNfcDta.disableDta());
-        verify(mMockService).disableDta();
-    }
-
-    @Test
-    public void testDisableDataWithRemoteException() throws RemoteException {
-        doThrow(new RemoteException()).when(mMockService).disableDta();
-
-        assertFalse(mNfcDta.disableDta());
-        verify(mMockService).disableDta();
-    }
-
-    @Test
-    public void testEnableServer() throws RemoteException {
-        when(mMockService.enableServer(mServiceName, mServiceSap, mMiu, mRwSize,
-                mTestCaseId)).thenReturn(true);
-
-        mNfcDta.enableServer(mServiceName, mServiceSap, mMiu, mRwSize, mTestCaseId);
-        verify(mMockService).enableServer(mServiceName, mServiceSap, mMiu, mRwSize, mTestCaseId);
-    }
-
-    @Test
-    public void testEnableServerWithRemoteException() throws RemoteException {
-        doThrow(new RemoteException()).when(mMockService).enableServer(mServiceName, mServiceSap,
-                mMiu,
-                mRwSize, mTestCaseId);
-
-        mNfcDta.enableServer(mServiceName, mServiceSap, mMiu, mRwSize, mTestCaseId);
-        verify(mMockService).enableServer(mServiceName, mServiceSap, mMiu, mRwSize, mTestCaseId);
-    }
-
-    @Test
-    public void testDisableServer() throws RemoteException {
-        assertTrue(mNfcDta.disableServer());
-        verify(mMockService).disableServer();
-    }
-
-    @Test
-    public void testDisableServerWithRemoteException() throws RemoteException {
-        doThrow(new RemoteException()).when(mMockService).disableServer();
-
-        assertFalse(mNfcDta.disableServer());
-        verify(mMockService).disableServer();
-    }
-
-    @Test
-    public void testEnableClient() throws RemoteException {
-        when(mMockService.enableClient(mServiceName, mMiu, mRwSize, mTestCaseId)).thenReturn(true);
-
-        mNfcDta.enableClient(mServiceName, mMiu, mRwSize, mTestCaseId);
-        verify(mMockService).enableClient(mServiceName, mMiu, mRwSize, mTestCaseId);
-    }
-
-    @Test
-    public void testEnableClientWithRemoteException() throws RemoteException {
-        doThrow(new RemoteException()).when(mMockService).enableClient(mServiceName, mMiu, mRwSize,
-                mTestCaseId);
-
-        mNfcDta.enableClient(mServiceName, mMiu, mRwSize, mTestCaseId);
-        verify(mMockService).enableClient(mServiceName, mMiu, mRwSize, mTestCaseId);
-    }
-
-    @Test
-    public void testDisableClient() throws RemoteException {
-        assertTrue(mNfcDta.disableClient());
-        verify(mMockService).disableClient();
-    }
-
-    @Test
-    public void testDisableClientWithRemoteException() throws RemoteException {
-        doThrow(new RemoteException()).when(mMockService).disableClient();
-
-        assertFalse(mNfcDta.disableClient());
-        verify(mMockService).disableClient();
-    }
-
-    @Test
-    public void testRegisterMessageService() throws RemoteException {
-        String msgServiceName = "sampleServiceName";
-        when(mMockService.registerMessageService(msgServiceName)).thenReturn(true);
-
-        mNfcDta.registerMessageService(msgServiceName);
-        verify(mMockService).registerMessageService(msgServiceName);
-    }
-
-    @Test
-    public void testRegisterMessageServiceWithRemoteException() throws RemoteException {
-        String msgServiceName = "sampleServiceName";
-        doThrow(new RemoteException()).when(mMockService).registerMessageService(msgServiceName);
-
-        assertFalse(mNfcDta.registerMessageService(msgServiceName));
-    }
-
-    @Test(expected = NullPointerException.class)
-    public void testGetInstanceWithNullPointerException() {
-        NfcDta.getInstance(null);
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testGetInstanceWithUnsupportedOperationExceptionForNfcAdapterContext() {
-        when(mMockNfcAdapter.getContext()).thenReturn(null);
-
-        NfcDta.getInstance(mMockNfcAdapter);
-    }
-}
diff --git a/nfc/tests/src/android/nfc/tech/NfcATest.java b/nfc/tests/src/android/nfc/tech/NfcATest.java
deleted file mode 100644
index 40076eb..0000000
--- a/nfc/tests/src/android/nfc/tech/NfcATest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc.tech;
-
-import static android.nfc.tech.NfcA.EXTRA_ATQA;
-import static android.nfc.tech.NfcA.EXTRA_SAK;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.nfc.ErrorCodes;
-import android.nfc.INfcTag;
-import android.nfc.Tag;
-import android.nfc.TransceiveResult;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.IOException;
-
-public class NfcATest {
-    @Mock
-    private Tag mMockTag;
-    @Mock
-    private INfcTag mMockTagService;
-    @Mock
-    private Bundle mMockBundle;
-    private NfcA mNfcA;
-    private final byte[] mSampleArray = new byte[] {1, 2, 3};
-
-    @Before
-    public void setUp() throws RemoteException {
-        MockitoAnnotations.initMocks(this);
-        when(mMockBundle.getShort(EXTRA_SAK)).thenReturn((short) 1);
-        when(mMockBundle.getByteArray(EXTRA_ATQA)).thenReturn(mSampleArray);
-        when(mMockTag.getTechExtras(TagTechnology.NFC_A)).thenReturn(mMockBundle);
-
-        mNfcA = new NfcA(mMockTag);
-    }
-
-    @Test
-    public void testGetNfcAWithTech() {
-        Tag mockTag = mock(Tag.class);
-        when(mockTag.getTechExtras(TagTechnology.NFC_A)).thenReturn(mMockBundle);
-        when(mockTag.hasTech(TagTechnology.NFC_A)).thenReturn(true);
-
-        assertNotNull(NfcA.get(mockTag));
-        verify(mockTag).getTechExtras(TagTechnology.NFC_A);
-        verify(mockTag).hasTech(TagTechnology.NFC_A);
-    }
-
-    @Test
-    public void testGetNfcAWithoutTech() {
-        when(mMockTag.hasTech(TagTechnology.NFC_A)).thenReturn(false);
-        assertNull(NfcA.get(mMockTag));
-    }
-
-    @Test
-    public void testGetAtga() {
-        assertNotNull(mNfcA.getAtqa());
-    }
-
-    @Test
-    public void testGetSak() {
-        assertEquals((short) 1, mNfcA.getSak());
-    }
-
-    @Test
-    public void testTransceive() throws IOException, RemoteException {
-        TransceiveResult mockTransceiveResult = mock(TransceiveResult.class);
-        when(mMockTag.getConnectedTechnology()).thenReturn(TagTechnology.NFC_A);
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTag.getServiceHandle()).thenReturn(1);
-        when(mMockTagService.transceive(1, mSampleArray, true))
-                .thenReturn(mockTransceiveResult);
-        when(mockTransceiveResult.getResponseOrThrow()).thenReturn(mSampleArray);
-
-        mNfcA.transceive(mSampleArray);
-        verify(mMockTag).getTagService();
-        verify(mMockTag).getServiceHandle();
-    }
-
-    @Test
-    public void testGetMaxTransceiveLength() throws RemoteException {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTagService.getMaxTransceiveLength(TagTechnology.NFC_A)).thenReturn(1);
-
-        mNfcA.getMaxTransceiveLength();
-        verify(mMockTag).getTagService();
-    }
-
-    @Test
-    public void testSetTimeout() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.setTimeout(TagTechnology.NFC_A, 1000)).thenReturn(
-                    ErrorCodes.SUCCESS);
-
-            mNfcA.setTimeout(1000);
-            verify(mMockTag).getTagService();
-            verify(mMockTagService).setTimeout(TagTechnology.NFC_A, 1000);
-        } catch (Exception e) {
-            fail("Unexpected exception during valid setTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testSetTimeoutInvalidTimeout() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.setTimeout(TagTechnology.NFC_A, -1)).thenReturn(
-                    ErrorCodes.ERROR_TIMEOUT);
-
-            assertThrows(IllegalArgumentException.class, () -> mNfcA.setTimeout(-1));
-        } catch (Exception e) {
-            fail("Unexpected exception during invalid setTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testSetTimeoutRemoteException() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.setTimeout(TagTechnology.NFC_A, 1000)).thenThrow(
-                    new RemoteException());
-
-            mNfcA.setTimeout(1000); // Should not throw an exception but log it
-            verify(mMockTag).getTagService();
-            verify(mMockTagService).setTimeout(TagTechnology.NFC_A, 1000);
-        } catch (Exception e) {
-            fail("Unexpected exception during RemoteException in setTimeout: " + e.getMessage());
-        }
-
-    }
-
-    @Test
-    public void testGetTimeout() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.getTimeout(TagTechnology.NFC_A)).thenReturn(2000);
-
-            assertEquals(2000, mNfcA.getTimeout());
-            verify(mMockTag).getTagService();
-            verify(mMockTagService).getTimeout(TagTechnology.NFC_A);
-        } catch (Exception e) {
-            fail("Unexpected exception during valid getTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testGetTimeoutRemoteException() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.getTimeout(TagTechnology.NFC_A)).thenThrow(new RemoteException());
-
-            assertEquals(0, mNfcA.getTimeout());
-        } catch (Exception e) {
-            fail("Unexpected exception during RemoteException in getTimeout: " + e.getMessage());
-        }
-    }
-}
diff --git a/nfc/tests/src/android/nfc/tech/NfcBTest.java b/nfc/tests/src/android/nfc/tech/NfcBTest.java
deleted file mode 100644
index 98d6070..0000000
--- a/nfc/tests/src/android/nfc/tech/NfcBTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.nfc.tech;
-
-import static android.nfc.tech.NfcB.EXTRA_APPDATA;
-import static android.nfc.tech.NfcB.EXTRA_PROTINFO;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.nfc.INfcTag;
-import android.nfc.Tag;
-import android.nfc.TransceiveResult;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.IOException;
-
-public class NfcBTest {
-    private final byte[] mSampleAppDate = new byte[] {1, 2, 3};
-    private final byte[] mSampleProtInfo = new byte[] {3, 2, 1};
-    @Mock
-    private Tag mMockTag;
-    @Mock
-    private Bundle mMockBundle;
-    @Mock
-    private INfcTag mMockTagService;
-    private NfcB mNfcB;
-
-    @Before
-    public void setUp() throws RemoteException {
-        MockitoAnnotations.initMocks(this);
-        when(mMockBundle.getByteArray(EXTRA_APPDATA)).thenReturn(mSampleAppDate);
-        when(mMockBundle.getByteArray(EXTRA_PROTINFO)).thenReturn(mSampleProtInfo);
-        when(mMockTag.getTechExtras(TagTechnology.NFC_B)).thenReturn(mMockBundle);
-
-        mNfcB = new NfcB(mMockTag);
-    }
-
-    @Test
-    public void testGetApplicationData() {
-        assertNotNull(mNfcB.getApplicationData());
-    }
-
-    @Test
-    public void testGetProtocolInfo() {
-        assertNotNull(mNfcB.getProtocolInfo());
-    }
-
-    @Test
-    public void testGetNfcBInstance() {
-        Tag tag = mock(Tag.class);
-        when(tag.hasTech(TagTechnology.NFC_B)).thenReturn(true);
-        when(tag.getTechExtras(TagTechnology.NFC_B)).thenReturn(mMockBundle);
-
-        assertNotNull(NfcB.get(tag));
-        verify(tag).hasTech(TagTechnology.NFC_B);
-        verify(tag).getTechExtras(TagTechnology.NFC_B);
-    }
-
-    @Test
-    public void testGetNfcBNullInstance() {
-        Tag tag = mock(Tag.class);
-        when(tag.hasTech(TagTechnology.NFC_B)).thenReturn(false);
-
-        assertNull(NfcB.get(tag));
-        verify(tag).hasTech(TagTechnology.NFC_B);
-        verify(tag, never()).getTechExtras(TagTechnology.NFC_B);
-    }
-
-
-    @Test
-    public void testTransceive() throws IOException, RemoteException {
-        byte[] sampleData = new byte[] {1, 2, 3, 4, 5};
-        TransceiveResult mockTransceiveResult = mock(TransceiveResult.class);
-        when(mMockTag.getConnectedTechnology()).thenReturn(TagTechnology.NFC_B);
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTag.getServiceHandle()).thenReturn(1);
-        when(mMockTagService.transceive(1, sampleData, true))
-                .thenReturn(mockTransceiveResult);
-        when(mockTransceiveResult.getResponseOrThrow()).thenReturn(sampleData);
-
-        mNfcB.transceive(sampleData);
-        verify(mMockTag).getTagService();
-        verify(mMockTag).getServiceHandle();
-    }
-
-    @Test
-    public void testGetMaxTransceiveLength() throws RemoteException {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTagService.getMaxTransceiveLength(TagTechnology.NFC_B)).thenReturn(1);
-
-        mNfcB.getMaxTransceiveLength();
-        verify(mMockTag).getTagService();
-    }
-}
diff --git a/nfc/tests/src/android/nfc/tech/NfcBarcodeTest.java b/nfc/tests/src/android/nfc/tech/NfcBarcodeTest.java
deleted file mode 100644
index 3aa4e2c..0000000
--- a/nfc/tests/src/android/nfc/tech/NfcBarcodeTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2012 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 android.nfc.tech;
-
-import static android.nfc.tech.NfcBarcode.EXTRA_BARCODE_TYPE;
-import static android.nfc.tech.NfcBarcode.TYPE_KOVIO;
-import static android.nfc.tech.NfcBarcode.TYPE_UNKNOWN;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-public class NfcBarcodeTest {
-    @Mock
-    private Tag mMockTag;
-    @Mock
-    private Bundle mMockBundle;
-    private NfcBarcode mNfcBarcode;
-
-    @Before
-    public void setUp() throws RemoteException {
-        MockitoAnnotations.initMocks(this);
-        when(mMockBundle.getInt(EXTRA_BARCODE_TYPE)).thenReturn(TYPE_KOVIO);
-        when(mMockTag.getTechExtras(TagTechnology.NFC_BARCODE)).thenReturn(mMockBundle);
-
-        mNfcBarcode = new NfcBarcode(mMockTag);
-    }
-
-    @Test
-    public void testGetNfcBarcodeInstance() {
-        Tag mockTag = mock(Tag.class);
-        when(mockTag.hasTech(TagTechnology.NFC_BARCODE)).thenReturn(true);
-        when(mockTag.getTechExtras(TagTechnology.NFC_BARCODE)).thenReturn(mMockBundle);
-
-        assertNotNull(NfcBarcode.get(mockTag));
-        verify(mockTag).hasTech(TagTechnology.NFC_BARCODE);
-        verify(mockTag).getTechExtras(TagTechnology.NFC_BARCODE);
-    }
-
-    @Test(expected = NullPointerException.class)
-    public void testGetNfcBarcodeInstanceWithException() {
-        Tag mockTag = mock(Tag.class);
-        when(mockTag.hasTech(TagTechnology.NFC_BARCODE)).thenReturn(true);
-        when(mockTag.getTechExtras(TagTechnology.NFC_BARCODE)).thenReturn(null);
-
-        assertNull(NfcBarcode.get(mockTag));
-        verify(mockTag).hasTech(TagTechnology.NFC_BARCODE);
-        verify(mockTag).getTechExtras(TagTechnology.NFC_BARCODE);
-    }
-
-    @Test
-    public void testGetNfcBarcodeWithoutTech() {
-        when(mMockTag.hasTech(TagTechnology.NFC_BARCODE)).thenReturn(false);
-
-        assertNull(NfcBarcode.get(mMockTag));
-    }
-
-    @Test
-    public void testGetType() {
-        int result = mNfcBarcode.getType();
-        assertEquals(TYPE_KOVIO, result);
-    }
-
-    @Test
-    public void testGetBarcodeWithTypeKovio() {
-        byte[] sampleId = "sampleId".getBytes();
-        when(mMockTag.getId()).thenReturn(sampleId);
-
-        assertEquals(sampleId, mNfcBarcode.getBarcode());
-        verify(mMockTag).getId();
-    }
-
-    @Test
-    public void testGetBarCodeTypeUnknown() throws RemoteException {
-        when(mMockBundle.getInt(EXTRA_BARCODE_TYPE)).thenReturn(TYPE_UNKNOWN);
-        when(mMockTag.getTechExtras(TagTechnology.NFC_BARCODE)).thenReturn(mMockBundle);
-        mNfcBarcode = new NfcBarcode(mMockTag);
-
-        assertNull(mNfcBarcode.getBarcode());
-        verify(mMockTag, never()).getId();
-    }
-}
diff --git a/nfc/tests/src/android/nfc/tech/NfcFTest.java b/nfc/tests/src/android/nfc/tech/NfcFTest.java
deleted file mode 100644
index 31a6943..0000000
--- a/nfc/tests/src/android/nfc/tech/NfcFTest.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc.tech;
-
-import static android.nfc.tech.NfcF.EXTRA_PMM;
-import static android.nfc.tech.NfcF.EXTRA_SC;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.nfc.ErrorCodes;
-import android.nfc.INfcTag;
-import android.nfc.Tag;
-import android.nfc.TransceiveResult;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.IOException;
-
-public class NfcFTest {
-    private final byte[] mSampleSystemCode = new byte[] {1, 2, 3};
-    private final byte[] mSampleManufacturer = new byte[] {3, 2, 1};
-    @Mock
-    private Tag mMockTag;
-    @Mock
-    private INfcTag mMockTagService;
-    @Mock
-    private Bundle mMockBundle;
-    private NfcF mNfcF;
-
-    @Before
-    public void setUp() throws RemoteException {
-        MockitoAnnotations.initMocks(this);
-        when(mMockBundle.getByteArray(EXTRA_SC)).thenReturn(mSampleSystemCode);
-        when(mMockBundle.getByteArray(EXTRA_PMM)).thenReturn(mSampleManufacturer);
-        when(mMockTag.getTechExtras(TagTechnology.NFC_F)).thenReturn(mMockBundle);
-
-        mNfcF = new NfcF(mMockTag);
-    }
-
-    @Test
-    public void testGetSystemCode() {
-        assertNotNull(mNfcF.getSystemCode());
-    }
-
-    @Test
-    public void testGetManufacturer() {
-        assertNotNull(mNfcF.getManufacturer());
-    }
-
-    @Test
-    public void testGetNfcFInstanceWithTech() {
-        Tag tag = mock(Tag.class);
-        when(tag.getTechExtras(TagTechnology.NFC_F)).thenReturn(mMockBundle);
-        when(tag.hasTech(TagTechnology.NFC_F)).thenReturn(true);
-
-        assertNotNull(NfcF.get(tag));
-        verify(tag).getTechExtras(TagTechnology.NFC_F);
-        verify(tag).hasTech(TagTechnology.NFC_F);
-    }
-
-    @Test
-    public void testGetNfcFInstanceWithoutTech() {
-        Tag tag = mock(Tag.class);
-        when(tag.hasTech(TagTechnology.NFC_F)).thenReturn(false);
-
-        assertNull(NfcF.get(tag));
-        verify(tag).hasTech(TagTechnology.NFC_F);
-        verify(tag, never()).getTechExtras(TagTechnology.NFC_F);
-    }
-
-    @Test
-    public void testTransceive() throws IOException, RemoteException {
-        byte[] sampleData = new byte[]{1, 2, 3, 4, 5};
-        TransceiveResult mockTransceiveResult = mock(TransceiveResult.class);
-        when(mMockTag.getConnectedTechnology()).thenReturn(TagTechnology.NFC_F);
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTag.getServiceHandle()).thenReturn(1);
-        when(mMockTagService.transceive(1, sampleData, true))
-                .thenReturn(mockTransceiveResult);
-        when(mockTransceiveResult.getResponseOrThrow()).thenReturn(sampleData);
-
-        mNfcF.transceive(sampleData);
-        verify(mMockTag).getTagService();
-        verify(mMockTag).getServiceHandle();
-    }
-
-    @Test
-    public void testGetMaxTransceiveLength() throws RemoteException {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTagService.getMaxTransceiveLength(TagTechnology.NFC_F)).thenReturn(1);
-
-        mNfcF.getMaxTransceiveLength();
-        verify(mMockTag).getTagService();
-    }
-
-    @Test
-    public void testGetTimeout() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.getTimeout(TagTechnology.NFC_F)).thenReturn(2000);
-
-            assertEquals(2000, mNfcF.getTimeout());
-            verify(mMockTag).getTagService();
-            verify(mMockTagService).getTimeout(TagTechnology.NFC_F);
-        } catch (Exception e) {
-            fail("Unexpected exception during valid getTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testGetTimeoutRemoteException() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.getTimeout(TagTechnology.NFC_F)).thenThrow(new RemoteException());
-
-            assertEquals(0, mNfcF.getTimeout());
-        } catch (Exception e) {
-            fail("Unexpected exception during RemoteException in getTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testSetTimeout() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.setTimeout(TagTechnology.NFC_F, 1000)).thenReturn(
-                    ErrorCodes.SUCCESS);
-
-            mNfcF.setTimeout(1000);
-            verify(mMockTag).getTagService();
-            verify(mMockTagService).setTimeout(TagTechnology.NFC_F, 1000);
-        } catch (Exception e) {
-            fail("Unexpected exception during valid setTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testSetTimeoutInvalidTimeout() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.setTimeout(TagTechnology.NFC_F, -1)).thenReturn(
-                    ErrorCodes.ERROR_TIMEOUT);
-
-            assertThrows(IllegalArgumentException.class, () -> mNfcF.setTimeout(-1));
-        } catch (Exception e) {
-            fail("Unexpected exception during invalid setTimeout: " + e.getMessage());
-        }
-    }
-
-    @Test
-    public void testSetTimeoutRemoteException() {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        try {
-            when(mMockTagService.setTimeout(TagTechnology.NFC_F, 1000)).thenThrow(
-                    new RemoteException());
-
-            mNfcF.setTimeout(1000);
-            verify(mMockTag).getTagService();
-            verify(mMockTagService).setTimeout(TagTechnology.NFC_F, 1000);
-        } catch (Exception e) {
-            fail("Unexpected exception during RemoteException in setTimeout: " + e.getMessage());
-        }
-    }
-}
diff --git a/nfc/tests/src/android/nfc/tech/NfcVTest.java b/nfc/tests/src/android/nfc/tech/NfcVTest.java
deleted file mode 100644
index 6a99921..0000000
--- a/nfc/tests/src/android/nfc/tech/NfcVTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2010 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 android.nfc.tech;
-
-import static android.nfc.tech.NfcV.EXTRA_DSFID;
-import static android.nfc.tech.NfcV.EXTRA_RESP_FLAGS;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.nfc.INfcTag;
-import android.nfc.Tag;
-import android.nfc.TransceiveResult;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.IOException;
-
-public class NfcVTest {
-    private final byte mSampleRespFlags = (byte) 1;
-    private final byte mSampleDsfId = (byte) 2;
-    @Mock
-    private Tag mMockTag;
-    @Mock
-    private INfcTag mMockTagService;
-    @Mock
-    private Bundle mMockBundle;
-    private NfcV mNfcV;
-
-    @Before
-    public void setUp() throws RemoteException {
-        MockitoAnnotations.initMocks(this);
-        when(mMockBundle.getByte(EXTRA_RESP_FLAGS)).thenReturn(mSampleRespFlags);
-        when(mMockBundle.getByte(EXTRA_DSFID)).thenReturn(mSampleDsfId);
-        when(mMockTag.getTechExtras(TagTechnology.NFC_V)).thenReturn(mMockBundle);
-
-        mNfcV = new NfcV(mMockTag);
-    }
-
-    @Test
-    public void testGetResponseFlag() {
-        assertEquals(mSampleRespFlags, mNfcV.getResponseFlags());
-    }
-
-    @Test
-    public void testGetDsfId() {
-        assertEquals(mSampleDsfId, mNfcV.getDsfId());
-    }
-
-    @Test
-    public void testGetNfcVInstance() {
-        Tag tag = mock(Tag.class);
-        when(tag.hasTech(TagTechnology.NFC_V)).thenReturn(true);
-        when(tag.getTechExtras(TagTechnology.NFC_V)).thenReturn(mMockBundle);
-
-        assertNotNull(NfcV.get(tag));
-        verify(tag).getTechExtras(TagTechnology.NFC_V);
-        verify(tag).hasTech(TagTechnology.NFC_V);
-    }
-
-    @Test
-    public void testGetNfcVNullInstance() {
-        Tag tag = mock(Tag.class);
-        when(tag.hasTech(TagTechnology.NFC_V)).thenReturn(false);
-
-        assertNull(NfcV.get(tag));
-        verify(tag, never()).getTechExtras(TagTechnology.NFC_V);
-        verify(tag).hasTech(TagTechnology.NFC_V);
-    }
-
-    @Test
-    public void testTransceive() throws IOException, RemoteException {
-        byte[] sampleData = new byte[] {1, 2, 3, 4, 5};
-        TransceiveResult mockTransceiveResult = mock(TransceiveResult.class);
-        when(mMockTag.getConnectedTechnology()).thenReturn(TagTechnology.NFC_V);
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTag.getServiceHandle()).thenReturn(1);
-        when(mMockTagService.transceive(1, sampleData, true))
-                .thenReturn(mockTransceiveResult);
-        when(mockTransceiveResult.getResponseOrThrow()).thenReturn(sampleData);
-
-        mNfcV.transceive(sampleData);
-        verify(mMockTag).getTagService();
-        verify(mMockTag).getServiceHandle();
-    }
-
-    @Test
-    public void testGetMaxTransceiveLength() throws RemoteException {
-        when(mMockTag.getTagService()).thenReturn(mMockTagService);
-        when(mMockTagService.getMaxTransceiveLength(TagTechnology.NFC_V)).thenReturn(1);
-
-        mNfcV.getMaxTransceiveLength();
-        verify(mMockTag).getTagService();
-    }
-}
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index db0704f..5c07f3a 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -36,12 +36,9 @@
     <string name="title_nearby_device_streaming" msgid="2727103756701741359">"هل تريد السماح لـ \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" ببث التطبيقات من <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> إلى <xliff:g id="DEVICE_NAME">%3$s</xliff:g>؟"</string>
     <string name="summary_nearby_device_streaming" msgid="70434958004946884">"‏سيتمكّن \"<xliff:g id="APP_NAME_0">%1$s</xliff:g>\" من الوصول إلى كل المحتوى المعروض أو الذي يتم تشغيله على <xliff:g id="DEVICE_NAME_1">%3$s</xliff:g>، بما في ذلك الملفات الصوتية والصور ومعلومات الدفع وكلمات المرور والرسائل.&lt;br/&gt;&lt;br/&gt;سيتمكّن \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" من بثّ التطبيقات إلى <xliff:g id="DEVICE_NAME_3">%3$s</xliff:g> إلى أن توقِف إمكانية استخدام هذا الإذن."</string>
     <string name="helper_summary_nearby_device_streaming" msgid="4712712177819370967">"يطلب \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن <xliff:g id="DEVICE_NAME">%2$s</xliff:g> لبثّ التطبيقات من <xliff:g id="DEVICE_TYPE">%3$s</xliff:g>"</string>
-    <!-- no translation found for title_sensor_device_streaming (2395553261097861497) -->
-    <skip />
-    <!-- no translation found for summary_sensor_device_streaming (3413105061195145547) -->
-    <skip />
-    <!-- no translation found for helper_summary_sensor_device_streaming (8860174545653786353) -->
-    <skip />
+    <string name="title_sensor_device_streaming" msgid="2395553261097861497">"‏يُرجى تأكيد سماحك لتطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ببثّ المحتوى الصوتي وميزات النظام بين <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> و&lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="summary_sensor_device_streaming" msgid="3413105061195145547">"‏سيتمكّن \"<xliff:g id="APP_NAME_0">%1$s</xliff:g>\" من الوصول إلى كل المحتوى الذي يتم تشغيله على \"<xliff:g id="DEVICE_NAME_1">%3$s</xliff:g>\".&lt;br/&gt;&lt;br/&gt;سيتمكّن \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" من بثّ المحتوى الصوتي إلى \"<xliff:g id="DEVICE_NAME_3">%3$s</xliff:g>\" إلى أن يتم إيقاف استخدام هذا الإذن."</string>
+    <string name="helper_summary_sensor_device_streaming" msgid="8860174545653786353">"يطلب \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\" لبثّ المحتوى الصوتي وميزات النظام بين أجهزتك."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"جهاز"</string>
     <string name="summary_generic" msgid="1761976003668044801">"سيتمكّن هذا التطبيق من مزامنة المعلومات، مثل اسم المتصل، بين هاتفك والجهاز المحدّد."</string>
     <string name="consent_yes" msgid="8344487259618762872">"السماح"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index f4a95a4..7224896 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -36,12 +36,9 @@
     <string name="title_nearby_device_streaming" msgid="2727103756701741359">"क्या &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> में मौजूद ऐप्लिकेशन को &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; पर स्ट्रीम करने की अनुमति देनी है?"</string>
     <string name="summary_nearby_device_streaming" msgid="70434958004946884">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> के पास ऐसे किसी भी कॉन्टेंट का ऐक्सेस होगा जो आपके <xliff:g id="DEVICE_NAME_1">%3$s</xliff:g> पर दिखता है या चलाया जाता है. इसमें ऑडियो, फ़ोटो, पेमेंट संबंधी जानकारी, पासवर्ड, और मैसेज शामिल हैं.&lt;br/&gt;&lt;br/&gt;<xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="DEVICE_NAME_3">%3$s</xliff:g> पर तब ऐप्लिकेशन को स्ट्रीम कर सकेगा, जब तक आप यह अनुमति हटा न दें."</string>
     <string name="helper_summary_nearby_device_streaming" msgid="4712712177819370967">"<xliff:g id="APP_NAME">%1$s</xliff:g> को <xliff:g id="DEVICE_NAME">%2$s</xliff:g> की ओर से, आपके <xliff:g id="DEVICE_TYPE">%3$s</xliff:g> में मौजूद ऐप्लिकेशन को स्ट्रीम करने की अनुमति चाहिए"</string>
-    <!-- no translation found for title_sensor_device_streaming (2395553261097861497) -->
-    <skip />
-    <!-- no translation found for summary_sensor_device_streaming (3413105061195145547) -->
-    <skip />
-    <!-- no translation found for helper_summary_sensor_device_streaming (8860174545653786353) -->
-    <skip />
+    <string name="title_sensor_device_streaming" msgid="2395553261097861497">"क्या &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> और &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; पर ऑडियो और सिस्टम की सुविधाएं स्ट्रीम करने की अनुमति देनी है?"</string>
+    <string name="summary_sensor_device_streaming" msgid="3413105061195145547">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> के पास, आपके <xliff:g id="DEVICE_NAME_1">%3$s</xliff:g> पर चलाए जाने वाले हर तरह के कॉन्टेंट का ऐक्सेस होगा.&lt;br/&gt;&lt;br/&gt;<xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="DEVICE_NAME_3">%3$s</xliff:g> पर तब तक ऑडियो स्ट्रीम कर पाएगा, जब तक आप इस अनुमति को हटा न दें."</string>
+    <string name="helper_summary_sensor_device_streaming" msgid="8860174545653786353">"<xliff:g id="DEVICE_NAME">%2$s</xliff:g> की ओर से <xliff:g id="APP_NAME">%1$s</xliff:g>, आपके डिवाइस की ऑडियो और सिस्टम की सुविधाओं को आपके दूसरे डिवाइसों पर स्ट्रीम करने की अनुमति मांग रहा है."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"डिवाइस"</string>
     <string name="summary_generic" msgid="1761976003668044801">"यह ऐप्लिकेशन, आपके फ़ोन और चुने हुए डिवाइस के बीच जानकारी सिंक करेगा. जैसे, कॉल करने वाले व्यक्ति का नाम"</string>
     <string name="consent_yes" msgid="8344487259618762872">"अनुमति दें"</string>
diff --git a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
index 5661868..0afec99 100644
--- a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
@@ -42,7 +42,7 @@
     <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Želite da napravite pristupni ključ da biste se prijavili u <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="choose_create_option_password_title" msgid="4481366993598649224">"Želite da sačuvate lozinku da biste se prijavili u <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Želite da sačuvate podatke za prijavljivanje za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <string name="passkey" msgid="632353688396759522">"pristupni kôd"</string>
+    <string name="passkey" msgid="632353688396759522">"pristupni ključ"</string>
     <string name="password" msgid="6738570945182936667">"lozinka"</string>
     <string name="passkeys" msgid="5733880786866559847">"pristupni kodovi"</string>
     <string name="passwords" msgid="5419394230391253816">"lozinke"</string>
@@ -61,7 +61,7 @@
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"Lozinki: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>"</string>
     <string name="more_options_usage_passkeys" msgid="5390320437243042237">"Pristupnih kodova: <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> akreditiva"</string>
-    <string name="passkey_before_subtitle" msgid="2448119456208647444">"Pristupni kôd"</string>
+    <string name="passkey_before_subtitle" msgid="2448119456208647444">"Pristupni ključ"</string>
     <string name="another_device" msgid="5147276802037801217">"Drugi uređaj"</string>
     <string name="other_password_manager" msgid="565790221427004141">"Drugi menadžeri lozinki"</string>
     <string name="close_sheet" msgid="1393792015338908262">"Zatvorite tabelu"</string>
diff --git a/packages/CredentialManager/res/values-sr/strings.xml b/packages/CredentialManager/res/values-sr/strings.xml
index d28cefe..8e823c4 100644
--- a/packages/CredentialManager/res/values-sr/strings.xml
+++ b/packages/CredentialManager/res/values-sr/strings.xml
@@ -42,7 +42,7 @@
     <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Желите да направите приступни кључ да бисте се пријавили у <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="choose_create_option_password_title" msgid="4481366993598649224">"Желите да сачувате лозинку да бисте се пријавили у <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Желите да сачувате податке за пријављивање за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <string name="passkey" msgid="632353688396759522">"приступни кôд"</string>
+    <string name="passkey" msgid="632353688396759522">"приступни кључ"</string>
     <string name="password" msgid="6738570945182936667">"лозинка"</string>
     <string name="passkeys" msgid="5733880786866559847">"приступни кодови"</string>
     <string name="passwords" msgid="5419394230391253816">"лозинке"</string>
@@ -61,7 +61,7 @@
     <string name="more_options_usage_passwords" msgid="1632047277723187813">"Лозинки: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>"</string>
     <string name="more_options_usage_passkeys" msgid="5390320437243042237">"Приступних кодова: <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>"</string>
     <string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> акредитива"</string>
-    <string name="passkey_before_subtitle" msgid="2448119456208647444">"Приступни кôд"</string>
+    <string name="passkey_before_subtitle" msgid="2448119456208647444">"Приступни кључ"</string>
     <string name="another_device" msgid="5147276802037801217">"Други уређај"</string>
     <string name="other_password_manager" msgid="565790221427004141">"Други менаџери лозинки"</string>
     <string name="close_sheet" msgid="1393792015338908262">"Затворите табелу"</string>
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/ActionButton.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/ActionButton.kt
index 04a2c07..b88fda7 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/ActionButton.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/ActionButton.kt
@@ -65,8 +65,8 @@
             imageVector = if (toggleState.value)
                 Icons.Outlined.Visibility else Icons.Outlined.VisibilityOff,
             contentDescription = if (toggleState.value)
-                stringResource(R.string.content_description_show_password) else
-                stringResource(R.string.content_description_hide_password),
+                stringResource(R.string.content_description_hide_password) else
+                stringResource(R.string.content_description_show_password),
             tint = MaterialTheme.colorScheme.onSurfaceVariant,
         )
     }
diff --git a/packages/CredentialManager/wear/res/values-fa/strings.xml b/packages/CredentialManager/wear/res/values-fa/strings.xml
index 8053769..a385094 100644
--- a/packages/CredentialManager/wear/res/values-fa/strings.xml
+++ b/packages/CredentialManager/wear/res/values-fa/strings.xml
@@ -25,7 +25,7 @@
     <string name="dialog_sign_in_options_button" msgid="448002958902615054">"گزینه‌های ورود به سیستم"</string>
     <string name="sign_in_options_title" msgid="6720572645638986680">"گزینه‌های ورود به سیستم"</string>
     <string name="provider_list_title" msgid="6803918216129492212">"مدیریت ورود به سیستم"</string>
-    <string name="choose_sign_in_title" msgid="3616025924746872202">"ورود به سیستم را انتخاب کنید"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"انتخاب روش ورود به سیستم"</string>
     <string name="choose_passkey_title" msgid="8459270617632817465">"گذرکلید را انتخاب کنید"</string>
     <string name="choose_password_title" msgid="7610721820858017214">"گذرواژه را انتخاب کنید"</string>
     <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ورود به سیستم در تلفن"</string>
diff --git a/packages/CredentialManager/wear/res/values-pt/strings.xml b/packages/CredentialManager/wear/res/values-pt/strings.xml
index c451b25..1a1c16a 100644
--- a/packages/CredentialManager/wear/res/values-pt/strings.xml
+++ b/packages/CredentialManager/wear/res/values-pt/strings.xml
@@ -25,7 +25,7 @@
     <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opções de login"</string>
     <string name="sign_in_options_title" msgid="6720572645638986680">"Opções de login"</string>
     <string name="provider_list_title" msgid="6803918216129492212">"Gerenciar logins"</string>
-    <string name="choose_sign_in_title" msgid="3616025924746872202">"Escolher opção de login"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Escolha um login"</string>
     <string name="choose_passkey_title" msgid="8459270617632817465">"Escolher chave de acesso"</string>
     <string name="choose_password_title" msgid="7610721820858017214">"Escolher senha"</string>
     <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Fazer login no smartphone"</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
index 170cb45..44990f7 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
@@ -47,19 +47,19 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Log;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.StringRes;
+
+import com.android.packageinstaller.common.EventResultPersister;
+import com.android.packageinstaller.common.UninstallEventReceiver;
 import com.android.packageinstaller.handheld.ErrorDialogFragment;
 import com.android.packageinstaller.handheld.UninstallAlertDialogFragment;
 import com.android.packageinstaller.television.ErrorFragment;
 import com.android.packageinstaller.television.UninstallAlertFragment;
 import com.android.packageinstaller.television.UninstallAppProgress;
-import com.android.packageinstaller.common.EventResultPersister;
-import com.android.packageinstaller.common.UninstallEventReceiver;
 import com.android.packageinstaller.v2.ui.UninstallLaunch;
 
-import java.util.List;
-
 /*
  * This activity presents UI to uninstall an application. Usually launched with intent
  * Intent.ACTION_UNINSTALL_PKG_COMMAND and attribute
@@ -181,12 +181,15 @@
         if (mDialogInfo.user == null) {
             mDialogInfo.user = Process.myUserHandle();
         } else {
-            List<UserHandle> profiles = userManager.getUserProfiles();
-            if (!profiles.contains(mDialogInfo.user)) {
-                Log.e(TAG, "User " + Process.myUserHandle() + " can't request uninstall "
-                        + "for user " + mDialogInfo.user);
-                showUserIsNotAllowed();
-                return;
+            if (!mDialogInfo.user.equals(Process.myUserHandle())) {
+                final boolean isCurrentUserProfileOwner = Process.myUserHandle().equals(
+                        userManager.getProfileParent(mDialogInfo.user));
+                if (!isCurrentUserProfileOwner) {
+                    Log.e(TAG, "User " + Process.myUserHandle() + " can't request uninstall "
+                            + "for user " + mDialogInfo.user);
+                    showUserIsNotAllowed();
+                    return;
+                }
             }
         }
 
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index d739aaf..933c512 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -10,19 +10,19 @@
 android_library {
     name: "SettingsLib",
     defaults: [
-        "SettingsLintDefaults",
         "SettingsLibAvatarPickerDefaults",
+        "SettingsLintDefaults",
     ],
 
     static_libs: [
         "androidx.localbroadcastmanager_localbroadcastmanager",
         "androidx.room_room-runtime",
         "androidx.sqlite_sqlite",
-        "zxing-core",
         "guava",
+        "zxing-core",
 
-        "WifiTrackerLibRes",
         "//frameworks/libs/systemui:iconloader",
+        "WifiTrackerLibRes",
         "setupdesign",
 
         "SettingsLibActionBarShadow",
@@ -31,8 +31,8 @@
         "SettingsLibAppPreference",
         "SettingsLibBannerMessagePreference",
         "SettingsLibBarChartPreference",
-        "SettingsLibButtonPreference",
         "SettingsLibBulletPreference",
+        "SettingsLibButtonPreference",
         "SettingsLibCardPreference",
         "SettingsLibCollapsingToolbarBaseActivity",
         "SettingsLibDeviceStateRotationLock",
@@ -50,6 +50,7 @@
         "SettingsLibProgressBar",
         "SettingsLibRestrictedLockUtils",
         "SettingsLibSearchWidget",
+        "SettingsLibSegmentedButtonPreference",
         "SettingsLibSelectorWithWidgetPreference",
         "SettingsLibSettingsSpinner",
         "SettingsLibSettingsTransition",
@@ -62,7 +63,7 @@
         "SettingsLibZeroStatePreference",
         "settingslib_media_flags_lib",
     ],
-    libs:[
+    libs: [
         // This flag library has been added in frameworks jar
         "aconfig_settingslib_flags_java_lib",
         "wifi_framework_aconfig_flags_lib",
@@ -118,8 +119,8 @@
         "legacy_avatar_picker_app_enabled",
     ],
     properties: [
-        "static_libs",
         "manifest",
+        "static_libs",
     ],
 }
 
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/GetPreferenceGraphApiHandler.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/GetPreferenceGraphApiHandler.kt
index 3c8d6ed..19fa507 100644
--- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/GetPreferenceGraphApiHandler.kt
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/GetPreferenceGraphApiHandler.kt
@@ -44,8 +44,8 @@
     ): PreferenceGraphProto {
         val builder = PreferenceGraphBuilder.of(application, callingPid, callingUid, request)
         if (request.screenKeys.isEmpty()) {
-            for (key in PreferenceScreenRegistry.preferenceScreens.keys) {
-                builder.addPreferenceScreenFromRegistry(key)
+            PreferenceScreenRegistry.preferenceScreenMetadataCreators.forEachKeyAsync {
+                builder.addPreferenceScreenFromRegistry(it)
             }
             for (provider in preferenceScreenProviders) {
                 builder.addPreferenceScreenProvider(provider)
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterApi.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterApi.kt
index de5731e..2fac545 100644
--- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterApi.kt
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGetterApi.kt
@@ -98,7 +98,7 @@
         val preferences = mutableMapOf<PreferenceCoordinate, PreferenceProto>()
         val flags = request.flags
         for ((screenKey, coordinates) in request.preferences.groupBy { it.screenKey }) {
-            val screenMetadata = PreferenceScreenRegistry[screenKey]
+            val screenMetadata = PreferenceScreenRegistry.create(application, screenKey)
             if (screenMetadata == null) {
                 for (coordinate in coordinates) {
                     errors[coordinate] = PreferenceGetterErrorCode.NOT_FOUND
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
index 2cf32de..f001fad 100644
--- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
@@ -141,7 +141,7 @@
         }
 
     suspend fun addPreferenceScreenFromRegistry(key: String): Boolean {
-        val metadata = PreferenceScreenRegistry[key] ?: return false
+        val metadata = PreferenceScreenRegistry.create(context, key) ?: return false
         return addPreferenceScreenMetadata(metadata)
     }
 
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt
index bef4bb2..3c870ac 100644
--- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt
@@ -112,7 +112,8 @@
         request: PreferenceSetterRequest,
     ): Int {
         val screenMetadata =
-            PreferenceScreenRegistry[request.screenKey] ?: return PreferenceSetterResult.UNSUPPORTED
+            PreferenceScreenRegistry.create(application, request.screenKey)
+                ?: return PreferenceSetterResult.UNSUPPORTED
         val key = request.key
         val metadata =
             screenMetadata.getPreferenceHierarchy(application).find(key)
diff --git a/packages/SettingsLib/Metadata/Android.bp b/packages/SettingsLib/Metadata/Android.bp
index 207637f..564c398 100644
--- a/packages/SettingsLib/Metadata/Android.bp
+++ b/packages/SettingsLib/Metadata/Android.bp
@@ -14,10 +14,9 @@
     ],
     srcs: [":SettingsLibMetadata-srcs"],
     static_libs: [
+        "SettingsLibDataStore",
         "androidx.annotation_annotation",
         "androidx.fragment_fragment",
-        "guava",
-        "SettingsLibDataStore",
     ],
     kotlincflags: ["-Xjvm-default=all"],
 }
diff --git a/packages/SettingsLib/Metadata/processor/src/com/android/settingslib/metadata/PreferenceScreenAnnotationProcessor.kt b/packages/SettingsLib/Metadata/processor/src/com/android/settingslib/metadata/PreferenceScreenAnnotationProcessor.kt
index 620d717..1049cce 100644
--- a/packages/SettingsLib/Metadata/processor/src/com/android/settingslib/metadata/PreferenceScreenAnnotationProcessor.kt
+++ b/packages/SettingsLib/Metadata/processor/src/com/android/settingslib/metadata/PreferenceScreenAnnotationProcessor.kt
@@ -16,7 +16,6 @@
 
 package com.android.settingslib.metadata
 
-import java.util.TreeMap
 import javax.annotation.processing.AbstractProcessor
 import javax.annotation.processing.ProcessingEnvironment
 import javax.annotation.processing.RoundEnvironment
@@ -33,8 +32,7 @@
 
 /** Processor to gather preference screens annotated with `@ProvidePreferenceScreen`. */
 class PreferenceScreenAnnotationProcessor : AbstractProcessor() {
-    private val screens = TreeMap<String, ConstructorType>()
-    private val overlays = mutableMapOf<String, String>()
+    private val screens = mutableListOf<Screen>()
     private val contextType: TypeMirror by lazy {
         processingEnv.elementUtils.getTypeElement("android.content.Context").asType()
     }
@@ -94,15 +92,10 @@
             )
             return
         }
-        val screenQualifiedName = qualifiedName.toString()
-        screens[screenQualifiedName] = constructorType
         val annotation = annotationMirrors.single { it.isElement(annotationElement) }
-        val overlay = annotation.getOverlay()
-        if (overlay != null) {
-            overlays.put(overlay, screenQualifiedName)?.let {
-                error("$overlay has been overlaid by $it", this)
-            }
-        }
+        val key = annotation.fieldValue<String>("value")!!
+        val overlay = annotation.fieldValue<Boolean>("overlay") == true
+        screens.add(Screen(key, overlay, qualifiedName.toString(), constructorType))
     }
 
     private fun codegen() {
@@ -119,68 +112,76 @@
     }
 
     private fun generateCode(outputPkg: String, outputClass: String, outputFun: String) {
-        for ((overlay, screen) in overlays) {
-            if (screens.remove(overlay) == null) {
-                warn("$overlay is overlaid by $screen but not annotated with @$ANNOTATION_NAME")
-            } else {
-                processingEnv.messager.printMessage(
-                    Diagnostic.Kind.NOTE,
-                    "$overlay is overlaid by $screen",
-                )
+        // sort by screen keys to make the output deterministic and naturally fit to FixedArrayMap
+        screens.sort()
+        val javaFileObject =
+            try {
+                processingEnv.filer.createSourceFile("$outputPkg.$outputClass")
+            } catch (e: Exception) {
+                // quick fix: gradle runs this processor twice unexpectedly
+                warn("cannot createSourceFile: $e")
+                return
             }
-        }
-        processingEnv.filer.createSourceFile("$outputPkg.$outputClass").openWriter().use {
+        javaFileObject.openWriter().use {
             it.write("package $outputPkg;\n\n")
-            it.write("import $PACKAGE.$PREFERENCE_SCREEN_METADATA;\n\n")
+            it.write("import $PACKAGE.FixedArrayMap;\n")
+            it.write("import $PACKAGE.FixedArrayMap.OrderedInitializer;\n")
+            it.write("import $PACKAGE.$CREATOR;\n\n")
             it.write("// Generated by annotation processor for @$ANNOTATION_NAME\n")
             it.write("public final class $outputClass {\n")
             it.write("  private $outputClass() {}\n\n")
-            it.write(
-                "  public static java.util.List<$PREFERENCE_SCREEN_METADATA> " +
-                    "$outputFun(android.content.Context context) {\n"
-            )
-            it.write(
-                "    java.util.ArrayList<$PREFERENCE_SCREEN_METADATA> screens = " +
-                    "new java.util.ArrayList<>(${screens.size});\n"
-            )
-            for ((screen, constructorType) in screens) {
+            it.write("  public static FixedArrayMap<String, $CREATOR> $outputFun() {\n")
+            val size = screens.size
+            it.write("    return new FixedArrayMap<>($size, $outputClass::init);\n")
+            it.write("  }\n\n")
+            fun Screen.write() {
+                it.write("    screens.put(\"$key\", context -> new $klass(")
                 when (constructorType) {
-                    ConstructorType.DEFAULT -> it.write("    screens.add(new $screen());\n")
-                    ConstructorType.CONTEXT -> it.write("    screens.add(new $screen(context));\n")
-                    ConstructorType.SINGLETON -> it.write("    screens.add($screen.INSTANCE);\n")
+                    ConstructorType.DEFAULT -> it.write("));")
+                    ConstructorType.CONTEXT -> it.write("context));")
                 }
+                if (overlay) it.write(" // overlay")
+                it.write("\n")
             }
-            for ((overlay, screen) in overlays) {
-                it.write("    // $overlay is overlaid by $screen\n")
+            it.write("  private static void init(OrderedInitializer<String, $CREATOR> screens) {\n")
+            var index = 0
+            while (index < size) {
+                val screen = screens[index]
+                var next = index + 1
+                while (next < size && screen.key == screens[next].key) next++
+                val n = next - index
+                if (n == 1) {
+                    screen.write()
+                } else if (n == 2 && screen.overlay && !screens[index + 1].overlay) {
+                    it.write("    // ${screen.klass} overlays ${screens[index + 1].klass}\n")
+                    screen.write()
+                } else {
+                    val msg = StringBuilder("${screen.key} is associated to")
+                    for (i in index until next) msg.append(" ${screens[i]}")
+                    processingEnv.messager.printMessage(Diagnostic.Kind.ERROR, msg)
+                }
+                index = next
             }
-            it.write("    return screens;\n")
-            it.write("  }\n")
-            it.write("}")
+            it.write("  }\n}")
         }
     }
 
     private fun AnnotationMirror.isElement(element: TypeElement) =
         processingEnv.typeUtils.isSameType(annotationType.asElement().asType(), element.asType())
 
-    private fun AnnotationMirror.getOverlay(): String? {
+    @Suppress("UNCHECKED_CAST")
+    private fun <T> AnnotationMirror.fieldValue(name: String): T? = field(name)?.value as? T
+
+    private fun AnnotationMirror.field(name: String): AnnotationValue? {
         for ((key, value) in elementValues) {
-            if (key.simpleName.contentEquals("overlay")) {
-                return if (value.isDefaultClassValue(key)) null else value.value.toString()
-            }
+            if (key.simpleName.contentEquals(name)) return value
         }
         return null
     }
 
-    private fun AnnotationValue.isDefaultClassValue(key: ExecutableElement) =
-        processingEnv.typeUtils.isSameType(
-            value as TypeMirror,
-            key.defaultValue.value as TypeMirror,
-        )
-
     private fun TypeElement.getConstructorType(): ConstructorType? {
         var constructor: ExecutableElement? = null
         for (element in enclosedElements) {
-            if (element.isKotlinObject()) return ConstructorType.SINGLETON
             if (element.kind != ElementKind.CONSTRUCTOR) continue
             if (!element.modifiers.contains(Modifier.PUBLIC)) continue
             if (constructor != null) return null
@@ -196,21 +197,27 @@
         }
     }
 
-    private fun Element.isKotlinObject() =
-        kind == ElementKind.FIELD &&
-            modifiers.run { contains(Modifier.PUBLIC) && contains(Modifier.STATIC) } &&
-            simpleName.toString() == "INSTANCE"
-
     private fun warn(msg: CharSequence) =
         processingEnv.messager.printMessage(Diagnostic.Kind.WARNING, msg)
 
     private fun error(msg: CharSequence, element: Element) =
         processingEnv.messager.printMessage(Diagnostic.Kind.ERROR, msg, element)
 
+    private data class Screen(
+        val key: String,
+        val overlay: Boolean,
+        val klass: String,
+        val constructorType: ConstructorType,
+    ) : Comparable<Screen> {
+        override fun compareTo(other: Screen): Int {
+            val diff = key.compareTo(other.key)
+            return if (diff != 0) diff else other.overlay.compareTo(overlay)
+        }
+    }
+
     private enum class ConstructorType {
         DEFAULT, // default constructor with no parameter
         CONTEXT, // constructor with a Context parameter
-        SINGLETON, // Kotlin object class
     }
 
     companion object {
@@ -218,6 +225,7 @@
         private const val ANNOTATION_NAME = "ProvidePreferenceScreen"
         private const val ANNOTATION = "$PACKAGE.$ANNOTATION_NAME"
         private const val PREFERENCE_SCREEN_METADATA = "PreferenceScreenMetadata"
+        private const val CREATOR = "PreferenceScreenMetadataCreator"
 
         private const val OPTIONS_NAME = "ProvidePreferenceScreenOptions"
         private const val OPTIONS = "$PACKAGE.$OPTIONS_NAME"
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/Annotations.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/Annotations.kt
index ea20a74..4bed795 100644
--- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/Annotations.kt
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/Annotations.kt
@@ -16,24 +16,20 @@
 
 package com.android.settingslib.metadata
 
-import kotlin.reflect.KClass
-
 /**
  * Annotation to provide preference screen.
  *
  * The annotated class must satisfy either condition:
  * - the primary constructor has no parameter
  * - the primary constructor has a single [android.content.Context] parameter
- * - it is a Kotlin object class
  *
- * @param overlay if specified, current annotated screen will overlay the given screen
+ * @param value unique preference screen key
+ * @param overlay if true, current annotated screen will overlay the screen that has identical key
  */
 @Retention(AnnotationRetention.SOURCE)
 @Target(AnnotationTarget.CLASS)
 @MustBeDocumented
-annotation class ProvidePreferenceScreen(
-    val overlay: KClass<out PreferenceScreenMetadata> = PreferenceScreenMetadata::class,
-)
+annotation class ProvidePreferenceScreen(val value: String, val overlay: Boolean = false)
 
 /**
  * Provides options for [ProvidePreferenceScreen] annotation processor.
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/FixedArrayMap.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/FixedArrayMap.kt
new file mode 100644
index 0000000..149331a
--- /dev/null
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/FixedArrayMap.kt
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2024 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.settingslib.metadata
+
+import java.util.function.Consumer
+
+/**
+ * A compact and immutable data structure provides [get] and for-each operations on ordered
+ * key-value entries.
+ *
+ * The implementation uses fixed-size array and no API is offered to modify entries. Actually,
+ * elements are provided in sorted order during constructor to simplify data management. As a
+ * result, this class is more lightweight compared with `ArrayMap`.
+ */
+@Suppress("UNCHECKED_CAST")
+class FixedArrayMap<K : Comparable<K>, V> {
+    private val array: Array<Any?>
+
+    /** Constructors with empty element. */
+    constructor() {
+        array = emptyArray()
+    }
+
+    /**
+     * Constructors.
+     *
+     * @param size the number of elements
+     * @param consumer initializer to provide exactly [size] elements *in sorted order*
+     */
+    constructor(size: Int, consumer: Consumer<OrderedInitializer<K, V>>) {
+        array = arrayOfNulls(size * 2)
+        val orderedInitializer = OrderedInitializer<K, V>(array)
+        consumer.accept(orderedInitializer)
+        orderedInitializer.verify()
+    }
+
+    /** Returns the number of elements. */
+    val size: Int
+        get() = array.size / 2
+
+    /**
+     * Returns a new [FixedArrayMap] that merged from current and given [FixedArrayMap] instance.
+     *
+     * [other] takes precedence for identical keys.
+     */
+    fun merge(other: FixedArrayMap<K, V>): FixedArrayMap<K, V> {
+        var newKeys = 0
+        other.forEachKey { if (get(it) == null) newKeys++ }
+        return FixedArrayMap(size + newKeys) { initializer ->
+            var index1 = 0
+            var index2 = 0
+            while (!initializer.isDone()) {
+                val key1 = if (index1 < array.size) array[index1] as K else null
+                val key2 = if (index2 < other.array.size) other.array[index2] as K else null
+                val diff =
+                    when {
+                        key1 == null -> 1
+                        key2 == null -> -1
+                        else -> key1.compareTo(key2)
+                    }
+                if (diff < 0) {
+                    initializer.put(key1!!, array[index1 + 1] as V)
+                    index1 += 2
+                } else {
+                    initializer.put(key2!!, other.array[index2 + 1] as V)
+                    index2 += 2
+                    if (diff == 0) index1 += 2
+                }
+            }
+        }
+    }
+
+    /** Traversals keys *in sorted order* and applies given action. */
+    fun forEachKey(action: (key: K) -> Unit) {
+        for (index in array.indices step 2) {
+            action(array[index] as K)
+        }
+    }
+
+    /** Traversals keys *in sorted order* and applies given action. */
+    suspend fun forEachKeyAsync(action: suspend (key: K) -> Unit) {
+        for (index in array.indices step 2) {
+            action(array[index] as K)
+        }
+    }
+
+    /** Traversals key-value entries *in sorted order* and applies given action. */
+    fun forEach(action: (key: K, value: V) -> Unit) {
+        for (index in array.indices step 2) {
+            action(array[index] as K, array[index + 1] as V)
+        }
+    }
+
+    /** Traversals key-value entries in sorted order and applies given action. */
+    suspend fun forEachAsync(action: suspend (key: K, value: V) -> Unit) {
+        for (index in array.indices step 2) {
+            action(array[index] as K, array[index + 1] as V)
+        }
+    }
+
+    /**
+     * Returns the value associated with given key.
+     *
+     * Binary-search algorithm is applied, so this operation takes O(log2(N)) at worst case.
+     */
+    operator fun get(key: K): V? {
+        var low = 0
+        var high = array.size / 2
+        while (low < high) {
+            val mid = (low + high).ushr(1) // safe from overflows
+            val diff = (array[mid * 2] as K).compareTo(key)
+            when {
+                diff < 0 -> low = mid + 1
+                diff > 0 -> high = mid
+                else -> return array[mid * 2 + 1] as V
+            }
+        }
+        return null
+    }
+
+    /** Initializer to provide key-value pairs *in sorted order*. */
+    class OrderedInitializer<K : Comparable<K>, V>
+    internal constructor(private val array: Array<Any?>) {
+        private var index = 0
+
+        internal val size: Int
+            get() = array.size
+
+        /** Returns whether all elements are added. */
+        fun isDone() = index == array.size
+
+        /** Adds a new key-value entry. The key must be provided in sorted order. */
+        fun put(key: K, value: V) {
+            array[index++] = key
+            array[index++] = value
+        }
+
+        internal fun verify() {
+            if (!isDone()) throw IllegalStateException("Missing items: ${index / 2} / ${size / 2}")
+            for (index in 2 until size step 2) {
+                if ((array[index - 2] as K) >= (array[index] as K)) {
+                    throw IllegalStateException("${array[index - 2]} >= ${array[index]}")
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceHierarchy.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceHierarchy.kt
index 9179f8f..876f615 100644
--- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceHierarchy.kt
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceHierarchy.kt
@@ -16,6 +16,8 @@
 
 package com.android.settingslib.metadata
 
+import android.content.Context
+
 /** A node in preference hierarchy that is associated with [PreferenceMetadata]. */
 open class PreferenceHierarchyNode internal constructor(val metadata: PreferenceMetadata) {
     /**
@@ -32,7 +34,8 @@
  *
  * A root hierarchy represents a preference screen. A sub-hierarchy represents a preference group.
  */
-class PreferenceHierarchy internal constructor(metadata: PreferenceMetadata) :
+class PreferenceHierarchy
+internal constructor(private val context: Context, metadata: PreferenceMetadata) :
     PreferenceHierarchyNode(metadata) {
 
     private val children = mutableListOf<PreferenceHierarchyNode>()
@@ -51,7 +54,8 @@
      *
      * @throws NullPointerException if screen is not registered to [PreferenceScreenRegistry]
      */
-    operator fun String.unaryPlus() = +PreferenceHierarchyNode(PreferenceScreenRegistry[this]!!)
+    operator fun String.unaryPlus() =
+        +PreferenceHierarchyNode(PreferenceScreenRegistry.create(context, this)!!)
 
     operator fun PreferenceHierarchyNode.unaryPlus() = also { children.add(it) }
 
@@ -79,7 +83,7 @@
     /** Adds a preference group to the hierarchy before given key. */
     fun addGroupBefore(key: String, metadata: PreferenceMetadata): PreferenceHierarchy {
         val (list, index) = findPreference(key) ?: (children to children.size)
-        return PreferenceHierarchy(metadata).also { list.add(index, it) }
+        return PreferenceHierarchy(context, metadata).also { list.add(index, it) }
     }
 
     /** Adds a preference to the hierarchy after given key. */
@@ -91,7 +95,7 @@
     /** Adds a preference group to the hierarchy after given key. */
     fun addGroupAfter(key: String, metadata: PreferenceMetadata): PreferenceHierarchy {
         val (list, index) = findPreference(key) ?: (children to children.size - 1)
-        return PreferenceHierarchy(metadata).also { list.add(index + 1, it) }
+        return PreferenceHierarchy(context, metadata).also { list.add(index + 1, it) }
     }
 
     private fun findPreference(key: String): Pair<MutableList<PreferenceHierarchyNode>, Int>? {
@@ -106,12 +110,13 @@
     }
 
     /** Adds a preference group to the hierarchy. */
-    operator fun PreferenceGroup.unaryPlus() = PreferenceHierarchy(this).also { children.add(it) }
+    operator fun PreferenceGroup.unaryPlus() =
+        PreferenceHierarchy(context, this).also { children.add(it) }
 
     /** Adds a preference group and returns its preference hierarchy. */
     @JvmOverloads
     fun addGroup(metadata: PreferenceGroup, order: Int? = null): PreferenceHierarchy =
-        PreferenceHierarchy(metadata).also {
+        PreferenceHierarchy(context, metadata).also {
             this.order = order
             children.add(it)
         }
@@ -128,7 +133,9 @@
      * @throws NullPointerException if screen is not registered to [PreferenceScreenRegistry]
      */
     fun addPreferenceScreen(screenKey: String) {
-        children.add(PreferenceHierarchy(PreferenceScreenRegistry[screenKey]!!))
+        children.add(
+            PreferenceHierarchy(context, PreferenceScreenRegistry.create(context, screenKey)!!)
+        )
     }
 
     /** Extensions to add more preferences to the hierarchy. */
@@ -175,5 +182,8 @@
  * Builder function to create [PreferenceHierarchy] in
  * [DSL](https://kotlinlang.org/docs/type-safe-builders.html) manner.
  */
-fun preferenceHierarchy(metadata: PreferenceMetadata, init: PreferenceHierarchy.() -> Unit) =
-    PreferenceHierarchy(metadata).also(init)
+fun preferenceHierarchy(
+    context: Context,
+    metadata: PreferenceMetadata,
+    init: PreferenceHierarchy.() -> Unit,
+) = PreferenceHierarchy(context, metadata).also(init)
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt
index c1edbdc..1e70a32 100644
--- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceMetadata.kt
@@ -22,7 +22,6 @@
 import androidx.annotation.AnyThread
 import androidx.annotation.DrawableRes
 import androidx.annotation.StringRes
-import androidx.fragment.app.Fragment
 
 /**
  * Interface provides preference metadata (title, summary, icon, etc.).
@@ -170,47 +169,3 @@
 /** Metadata of preference category. */
 @AnyThread
 open class PreferenceCategory(override val key: String, override val title: Int) : PreferenceGroup
-
-/** Metadata of preference screen. */
-@AnyThread
-interface PreferenceScreenMetadata : PreferenceMetadata {
-
-    /**
-     * The screen title resource, which precedes [getScreenTitle] if provided.
-     *
-     * By default, screen title is same with [title].
-     */
-    val screenTitle: Int
-        get() = title
-
-    /** Returns dynamic screen title, use [screenTitle] whenever possible. */
-    fun getScreenTitle(context: Context): CharSequence? = null
-
-    /** Returns the fragment class to show the preference screen. */
-    fun fragmentClass(): Class<out Fragment>?
-
-    /**
-     * Indicates if [getPreferenceHierarchy] returns a complete hierarchy of the preference screen.
-     *
-     * If `true`, the result of [getPreferenceHierarchy] will be used to inflate preference screen.
-     * Otherwise, it is an intermediate state called hybrid mode, preference hierarchy is
-     * represented by other ways (e.g. XML resource) and [PreferenceMetadata]s in
-     * [getPreferenceHierarchy] will only be used to bind UI widgets.
-     */
-    fun hasCompleteHierarchy(): Boolean = true
-
-    /**
-     * Returns the hierarchy of preference screen.
-     *
-     * The implementation MUST include all preferences into the hierarchy regardless of the runtime
-     * conditions. DO NOT check any condition (except compile time flag) before adding a preference.
-     */
-    fun getPreferenceHierarchy(context: Context): PreferenceHierarchy
-
-    /**
-     * Returns the [Intent] to show current preference screen.
-     *
-     * @param metadata the preference to locate when show the screen
-     */
-    fun getLaunchIntent(context: Context, metadata: PreferenceMetadata?): Intent? = null
-}
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenMetadata.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenMetadata.kt
new file mode 100644
index 0000000..a2dcefb
--- /dev/null
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenMetadata.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 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.settingslib.metadata
+
+import android.content.Context
+import android.content.Intent
+import androidx.annotation.AnyThread
+import androidx.fragment.app.Fragment
+
+/** Metadata of preference screen. */
+@AnyThread
+interface PreferenceScreenMetadata : PreferenceMetadata {
+
+    /**
+     * The screen title resource, which precedes [getScreenTitle] if provided.
+     *
+     * By default, screen title is same with [title].
+     */
+    val screenTitle: Int
+        get() = title
+
+    /** Returns dynamic screen title, use [screenTitle] whenever possible. */
+    fun getScreenTitle(context: Context): CharSequence? = null
+
+    /** Returns the fragment class to show the preference screen. */
+    fun fragmentClass(): Class<out Fragment>?
+
+    /**
+     * Indicates if [getPreferenceHierarchy] returns a complete hierarchy of the preference screen.
+     *
+     * If `true`, the result of [getPreferenceHierarchy] will be used to inflate preference screen.
+     * Otherwise, it is an intermediate state called hybrid mode, preference hierarchy is
+     * represented by other ways (e.g. XML resource) and [PreferenceMetadata]s in
+     * [getPreferenceHierarchy] will only be used to bind UI widgets.
+     */
+    fun hasCompleteHierarchy(): Boolean = true
+
+    /**
+     * Returns the hierarchy of preference screen.
+     *
+     * The implementation MUST include all preferences into the hierarchy regardless of the runtime
+     * conditions. DO NOT check any condition (except compile time flag) before adding a preference.
+     */
+    fun getPreferenceHierarchy(context: Context): PreferenceHierarchy
+
+    /**
+     * Returns the [Intent] to show current preference screen.
+     *
+     * @param metadata the preference to locate when show the screen
+     */
+    fun getLaunchIntent(context: Context, metadata: PreferenceMetadata?): Intent? = null
+}
+
+/** Creator of [PreferenceScreenMetadata]. */
+fun interface PreferenceScreenMetadataCreator {
+
+    /**
+     * Creates a new [PreferenceScreenMetadata].
+     *
+     * @param context application context to create the PreferenceScreenMetadata
+     */
+    fun create(context: Context): PreferenceScreenMetadata
+}
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt
index ff09910..6cf39f3 100644
--- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt
@@ -18,11 +18,6 @@
 
 import android.content.Context
 import com.android.settingslib.datastore.KeyValueStore
-import com.google.common.base.Supplier
-import com.google.common.base.Suppliers
-import com.google.common.collect.ImmutableMap
-
-private typealias PreferenceScreenMap = ImmutableMap<String, PreferenceScreenMetadata>
 
 /** Registry of all available preference screens in the app. */
 object PreferenceScreenRegistry : ReadWritePermitProvider {
@@ -30,12 +25,12 @@
     /** Provider of key-value store. */
     private lateinit var keyValueStoreProvider: KeyValueStoreProvider
 
-    private var preferenceScreensSupplier: Supplier<PreferenceScreenMap> = Supplier {
-        ImmutableMap.of()
-    }
-
-    val preferenceScreens: PreferenceScreenMap
-        get() = preferenceScreensSupplier.get()
+    /**
+     * Creators of all available [PreferenceScreenMetadata]s.
+     *
+     * The map key is preference screen key.
+     */
+    var preferenceScreenMetadataCreators = FixedArrayMap<String, PreferenceScreenMetadataCreator>()
 
     private var readWritePermitProvider: ReadWritePermitProvider =
         object : ReadWritePermitProvider {}
@@ -54,26 +49,9 @@
     fun getKeyValueStore(context: Context, preference: PreferenceMetadata): KeyValueStore? =
         keyValueStoreProvider.getKeyValueStore(context, preference)
 
-    /** Sets supplier to provide available preference screens. */
-    fun setPreferenceScreensSupplier(supplier: Supplier<List<PreferenceScreenMetadata>>) {
-        preferenceScreensSupplier =
-            Suppliers.memoize {
-                val screensBuilder = ImmutableMap.builder<String, PreferenceScreenMetadata>()
-                for (screen in supplier.get()) screensBuilder.put(screen.key, screen)
-                screensBuilder.buildOrThrow()
-            }
-    }
-
-    /** Sets available preference screens. */
-    fun setPreferenceScreens(vararg screens: PreferenceScreenMetadata) {
-        val screensBuilder = ImmutableMap.builder<String, PreferenceScreenMetadata>()
-        for (screen in screens) screensBuilder.put(screen.key, screen)
-        preferenceScreensSupplier = Suppliers.ofInstance(screensBuilder.buildOrThrow())
-    }
-
-    /** Returns [PreferenceScreenMetadata] of particular key. */
-    operator fun get(key: String?): PreferenceScreenMetadata? =
-        if (key != null) preferenceScreens[key] else null
+    /** Creates [PreferenceScreenMetadata] of particular screen key. */
+    fun create(context: Context, screenKey: String?): PreferenceScreenMetadata? =
+        screenKey?.let { preferenceScreenMetadataCreators[it]?.create(context.applicationContext) }
 
     /**
      * Sets the provider to check read write permit. Read and write requests are denied by default.
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt
index 991d5b7..e237a6a 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt
@@ -83,7 +83,7 @@
     @XmlRes protected open fun getPreferenceScreenResId(context: Context): Int = 0
 
     protected fun getPreferenceScreenCreator(context: Context): PreferenceScreenCreator? =
-        (PreferenceScreenRegistry[getPreferenceScreenBindingKey(context)]
+        (PreferenceScreenRegistry.create(context, getPreferenceScreenBindingKey(context))
                 as? PreferenceScreenCreator)
             ?.run { if (isFlagEnabled(context)) this else null }
 
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
index a9e20f28..91abd8b 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
@@ -220,7 +220,7 @@
         /** Updates preference screen that has incomplete hierarchy. */
         @JvmStatic
         fun bind(preferenceScreen: PreferenceScreen) {
-            PreferenceScreenRegistry[preferenceScreen.key]?.run {
+            PreferenceScreenRegistry.create(preferenceScreen.context, preferenceScreen.key)?.run {
                 if (!hasCompleteHierarchy()) {
                     val preferenceBindingFactory =
                         (this as? PreferenceScreenCreator)?.preferenceBindingFactory ?: return
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenFactory.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenFactory.kt
index 7f99d7a..211b3bd 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenFactory.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenFactory.kt
@@ -81,8 +81,8 @@
      *
      * The screen must be registered in [PreferenceScreenFactory] and provide a complete hierarchy.
      */
-    fun createBindingScreen(screenKey: String?): PreferenceScreen? {
-        val metadata = PreferenceScreenRegistry[screenKey] ?: return null
+    fun createBindingScreen(context: Context, screenKey: String?): PreferenceScreen? {
+        val metadata = PreferenceScreenRegistry.create(context, screenKey) ?: return null
         if (metadata is PreferenceScreenCreator && metadata.hasCompleteHierarchy()) {
             return metadata.createPreferenceScreen(this)
         }
@@ -93,11 +93,12 @@
         /** Creates [PreferenceScreen] from [PreferenceScreenRegistry]. */
         @JvmStatic
         fun createBindingScreen(preference: Preference): PreferenceScreen? {
+            val context = preference.context
             val preferenceScreenCreator =
-                (PreferenceScreenRegistry[preference.key] as? PreferenceScreenCreator)
-                    ?: return null
+                (PreferenceScreenRegistry.create(context, preference.key)
+                    as? PreferenceScreenCreator) ?: return null
             if (!preferenceScreenCreator.hasCompleteHierarchy()) return null
-            val factory = PreferenceScreenFactory(preference.context)
+            val factory = PreferenceScreenFactory(context)
             val preferenceScreen = preferenceScreenCreator.createPreferenceScreen(factory)
             factory.preferenceManager.setPreferences(preferenceScreen)
             return preferenceScreen
diff --git a/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/PreferenceBindingTestUtils.kt b/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/PreferenceBindingTestUtils.kt
index 00bad52..220614b 100644
--- a/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/PreferenceBindingTestUtils.kt
+++ b/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/PreferenceBindingTestUtils.kt
@@ -19,18 +19,27 @@
 import android.content.Context
 import androidx.annotation.VisibleForTesting
 import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
 import com.android.settingslib.metadata.PersistentPreference
 import com.android.settingslib.metadata.PreferenceMetadata
 
 /** Creates [Preference] widget and binds with metadata. */
+@Suppress("UNCHECKED_CAST")
 @VisibleForTesting
-fun <P : Preference> PreferenceMetadata.createAndBindWidget(context: Context): P {
+fun <P : Preference> PreferenceMetadata.createAndBindWidget(
+    context: Context,
+    preferenceScreen: PreferenceScreen? = null,
+): P {
     val binding = PreferenceBindingFactory.defaultFactory.getPreferenceBinding(this)!!
     return (binding.createWidget(context) as P).also {
         if (this is PersistentPreference<*>) {
-            storage(context)?.let { keyValueStore ->
+            storage(context).let { keyValueStore ->
                 it.preferenceDataStore = PreferenceDataStoreAdapter(keyValueStore)
             }
+            // Attach preference to preference screen, otherwise `Preference.performClick` does not
+            // interact with underlying datastore
+            (preferenceScreen ?: PreferenceScreenFactory(context).getOrCreatePreferenceScreen())
+                .addPreference(it)
         }
         binding.bind(it, this)
     }
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-fr-rCA/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-fr-rCA/strings.xml
index 8f0d572..da74cf6 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-fr-rCA/strings.xml
@@ -19,6 +19,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="enabled_by_admin" msgid="6630472777476410137">"Activé par l\'administrateur"</string>
     <string name="disabled_by_admin" msgid="4023569940620832713">"Désactivé par l\'administrateur"</string>
-    <string name="enabled_by_advanced_protection" msgid="6236917660829422499">"Activé par la protection avancée"</string>
-    <string name="disabled_by_advanced_protection" msgid="369596009193239632">"Désactivé par la protection avancée"</string>
+    <string name="enabled_by_advanced_protection" msgid="6236917660829422499">"Activée par la protection avancée"</string>
+    <string name="disabled_by_advanced_protection" msgid="369596009193239632">"Désactivée par la protection avancée"</string>
 </resources>
diff --git a/packages/SettingsLib/SegmentedButtonPreference/Android.bp b/packages/SettingsLib/SegmentedButtonPreference/Android.bp
new file mode 100644
index 0000000..6522e98
--- /dev/null
+++ b/packages/SettingsLib/SegmentedButtonPreference/Android.bp
@@ -0,0 +1,33 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_library {
+    name: "SettingsLibSegmentedButtonPreference",
+    use_resource_processor: true,
+    defaults: [
+        "SettingsLintDefaults",
+    ],
+
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.kt",
+    ],
+    resource_dirs: ["res"],
+
+    static_libs: [
+        "SettingsLibSettingsTheme",
+        "androidx.annotation_annotation",
+        "androidx.preference_preference",
+    ],
+    sdk_version: "system_current",
+    min_sdk_version: "21",
+    apex_available: [
+        "//apex_available:platform",
+    ],
+}
diff --git a/packages/SettingsLib/SegmentedButtonPreference/AndroidManifest.xml b/packages/SettingsLib/SegmentedButtonPreference/AndroidManifest.xml
new file mode 100644
index 0000000..d71bc36
--- /dev/null
+++ b/packages/SettingsLib/SegmentedButtonPreference/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.settingslib.widget.preference.segmentedbutton">
+
+    <uses-sdk android:minSdkVersion="21" />
+
+</manifest>
diff --git a/packages/SettingsLib/SegmentedButtonPreference/res/layout/settingslib_expressive_preference_segmentedbutton.xml b/packages/SettingsLib/SegmentedButtonPreference/res/layout/settingslib_expressive_preference_segmentedbutton.xml
new file mode 100644
index 0000000..12e2872
--- /dev/null
+++ b/packages/SettingsLib/SegmentedButtonPreference/res/layout/settingslib_expressive_preference_segmentedbutton.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2024 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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+
+    <com.google.android.material.button.MaterialButtonToggleGroup
+        android:id="@+id/button_group"
+        style="@style/Widget.Material3Expressive.MaterialButtonGroup.Connected"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:singleSelection="true"
+        app:selectionRequired="true"
+        app:checkedButton="@id/button_1">
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/button_1"
+            android:layout_weight="1"
+            app:iconPadding="0dp"
+            app:iconGravity="textStart"
+            style="@style/SettingsLibButtonStyle.Expressive.Tonal.Large"/>
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/button_2"
+            android:layout_weight="1"
+            app:iconPadding="0dp"
+            app:iconGravity="textStart"
+            style="@style/SettingsLibButtonStyle.Expressive.Tonal.Large"/>
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/button_3"
+            android:layout_weight="1"
+            app:iconPadding="0dp"
+            app:iconGravity="textStart"
+            style="@style/SettingsLibButtonStyle.Expressive.Tonal.Large"/>
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/button_4"
+            android:layout_weight="1"
+            app:iconPadding="0dp"
+            app:iconGravity="textStart"
+            style="@style/SettingsLibButtonStyle.Expressive.Tonal.Large"/>
+    </com.google.android.material.button.MaterialButtonToggleGroup>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:id="@+id/button_group_text"
+        android:orientation="horizontal"
+        android:gravity="center"
+        android:paddingTop="@dimen/settingslib_expressive_space_extrasmall4">
+
+        <TextView
+            android:id="@+id/button_1_text"
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:textAppearance="@style/TextAppearance.SettingsLib.TitleSmall.Emphasized"
+            android:textColor="@color/settingslib_materialColorOnSurface" />
+
+        <TextView
+            android:id="@+id/button_2_text"
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:textAppearance="@style/TextAppearance.SettingsLib.TitleSmall.Emphasized"
+            android:textColor="@color/settingslib_materialColorOnSurface" />
+
+        <TextView
+            android:id="@+id/button_3_text"
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:textAppearance="@style/TextAppearance.SettingsLib.TitleSmall.Emphasized"
+            android:textColor="@color/settingslib_materialColorOnSurface" />
+
+        <TextView
+            android:id="@+id/button_4_text"
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:textAppearance="@style/TextAppearance.SettingsLib.TitleSmall.Emphasized"
+            android:textColor="@color/settingslib_materialColorOnSurface" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/SegmentedButtonPreference/src/com/android/settingslib/widget/SegmentedButtonPreference.kt b/packages/SettingsLib/SegmentedButtonPreference/src/com/android/settingslib/widget/SegmentedButtonPreference.kt
new file mode 100644
index 0000000..b133969
--- /dev/null
+++ b/packages/SettingsLib/SegmentedButtonPreference/src/com/android/settingslib/widget/SegmentedButtonPreference.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2024 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.settingslib.widget
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View.GONE
+import android.view.View.VISIBLE
+import android.widget.TextView
+import androidx.annotation.DrawableRes
+import androidx.preference.Preference
+import androidx.preference.PreferenceViewHolder
+import com.android.settingslib.widget.preference.segmentedbutton.R
+import com.google.android.material.button.MaterialButton
+import com.google.android.material.button.MaterialButtonToggleGroup
+
+class SegmentedButtonPreference @JvmOverloads constructor(
+    context: Context,
+    attrs: AttributeSet? = null,
+    defStyleAttr: Int = 0,
+    defStyleRes: Int = 0
+) : Preference(context, attrs, defStyleAttr, defStyleRes), GroupSectionDividerMixin {
+    private var buttonGroup: MaterialButtonToggleGroup? = null
+    private var buttonLabels: MutableList<TextView> = mutableListOf()
+    private var buttonCheckedListener: MaterialButtonToggleGroup.OnButtonCheckedListener? = null
+
+    init {
+        layoutResource = R.layout.settingslib_expressive_preference_segmentedbutton
+    }
+
+    override fun onBindViewHolder(holder: PreferenceViewHolder) {
+        super.onBindViewHolder(holder)
+        holder.isDividerAllowedBelow = false
+        holder.isDividerAllowedAbove = false
+
+        buttonGroup = holder.findViewById(R.id.button_group) as MaterialButtonToggleGroup?
+        buttonLabels.add(holder.findViewById(R.id.button_1_text) as TextView)
+        buttonLabels.add(holder.findViewById(R.id.button_2_text) as TextView)
+        buttonLabels.add(holder.findViewById(R.id.button_3_text) as TextView)
+        buttonLabels.add(holder.findViewById(R.id.button_4_text) as TextView)
+    }
+
+    fun setupButton(index: Int, text: String, @DrawableRes icon: Int) {
+        if (index in 0 until buttonLabels.size) {
+            (buttonGroup?.getChildAt(index) as? MaterialButton)?.setIconResource(icon)
+            buttonLabels[index].text = text
+        }
+    }
+
+    fun setButtonVisibility(index: Int, visible: Boolean) {
+        if (index in 0 until buttonLabels.size) {
+            (buttonGroup?.getChildAt(index) as? MaterialButton)?.visibility =
+                if (visible) VISIBLE else GONE
+
+            buttonLabels[index].visibility = if (visible) VISIBLE else GONE
+        }
+    }
+
+    fun setButtonEnabled(index: Int, enabled: Boolean) {
+        if (index in 0 until buttonLabels.size) {
+            (buttonGroup?.getChildAt(index) as? MaterialButton)?.isEnabled = enabled
+        }
+    }
+
+    fun setOnButtonClickListener(listener: MaterialButtonToggleGroup.OnButtonCheckedListener) {
+        buttonCheckedListener = listener
+        buttonGroup?.addOnButtonCheckedListener (listener)
+    }
+
+    fun removeOnButtonClickListener() {
+        buttonCheckedListener?.let { buttonGroup?.removeOnButtonCheckedListener(it) }
+        buttonCheckedListener = null
+    }
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color/settingslib_expressive_button_outline_color_selector.xml b/packages/SettingsLib/SettingsTheme/res/color/settingslib_expressive_button_outline_color_selector.xml
new file mode 100644
index 0000000..5084f11
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color/settingslib_expressive_button_outline_color_selector.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:color="@android:color/transparent"/>
+    <item android:color="?attr/colorOutlineVariant"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color/settingslib_expressive_button_outlined_background_color_selector.xml b/packages/SettingsLib/SettingsTheme/res/color/settingslib_expressive_button_outlined_background_color_selector.xml
new file mode 100644
index 0000000..ed05cdd
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color/settingslib_expressive_button_outlined_background_color_selector.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:state_checked="true"
+        android:alpha="0.12"
+        android:color="?attr/colorOnSurface"/>
+    <item android:state_checked="true" android:color="?attr/colorContainerChecked"/>
+    <item android:state_checkable="true" android:color="?attr/colorContainerUnchecked"/>
+    <item android:color="?attr/colorContainer" />
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/color/settingslib_expressive_filled_button_color.xml b/packages/SettingsLib/SettingsTheme/res/color/settingslib_expressive_filled_button_color.xml
new file mode 100644
index 0000000..678bec4
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/color/settingslib_expressive_filled_button_color.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false"
+        android:alpha="0.12" android:color="@color/settingslib_materialColorOnSurface"/>
+    <item android:state_checked="true" android:color="@color/settingslib_materialColorPrimary"/>
+    <item android:state_checkable="true" android:color="@color/settingslib_materialColorSurfaceContainer"/>
+    <item android:color="@color/settingslib_materialColorPrimary" />
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml
index 2261e58..2776544 100644
--- a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml
+++ b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml
@@ -57,6 +57,7 @@
         android:id="@+id/collapse_button"
         app:layout_constraintTop_toBottomOf="@id/settingslib_expressive_learn_more"
         app:layout_constraintStart_toStartOf="parent"
+        android:textColor="@color/settingslib_materialColorOnSurface"
         android:text="@string/settingslib_expressive_text_expand"
         app:icon="@drawable/settingslib_expressive_icon_expand"
         style="@style/SettingslibTextButtonStyle.Expressive"/>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/styles_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/styles_expressive.xml
index 9d3d70b..b5f22b7 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v31/styles_expressive.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v31/styles_expressive.xml
@@ -17,27 +17,16 @@
 
 <resources>
     <style name="SettingsLibButtonStyle.Expressive.Filled"
-        parent="@style/Widget.Material3.Button">
+        parent="@style/Widget.Material3Expressive.Button.Icon">
         <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
         <item name="android:gravity">center</item>
-        <item name="android:minWidth">@dimen/settingslib_expressive_space_medium4</item>
-        <item name="android:minHeight">@dimen/settingslib_expressive_space_medium4</item>
-        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_extrasmall5</item>
-        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small1</item>
-        <item name="android:backgroundTint">@color/settingslib_materialColorPrimary</item>
         <item name="android:textAppearance">@style/TextAppearance.SettingsLib.LabelLarge</item>
-        <item name="android:textColor">@color/settingslib_materialColorOnPrimary</item>
-        <item name="iconGravity">textStart</item>
-        <item name="iconTint">@color/settingslib_materialColorOnPrimary</item>
-        <item name="iconSize">@dimen/settingslib_expressive_space_small4</item>
     </style>
 
     <style name="SettingsLibButtonStyle.Expressive.Filled.Large">
-        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_small1</item>
-        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small4</item>
-        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.TitleMedium</item>
+        <item name="materialSizeOverlay">@style/SizeOverlay.Material3Expressive.Button.Medium</item>
     </style>
 
     <style name="SettingsLibButtonStyle.Expressive.Filled.Extra"
@@ -45,28 +34,34 @@
         <item name="android:layout_width">match_parent</item>
     </style>
 
-    <style name="SettingsLibButtonStyle.Expressive.Tonal"
-        parent="@style/Widget.Material3.Button.TonalButton">
+    <style name="SettingsLibButtonStyle.Expressive.Icon.Filled"
+        parent="@style/Widget.Material3Expressive.Button.IconButton.Filled">
         <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
         <item name="android:gravity">center</item>
-        <item name="android:minWidth">@dimen/settingslib_expressive_space_medium4</item>
-        <item name="android:minHeight">@dimen/settingslib_expressive_space_medium4</item>
-        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_extrasmall5</item>
-        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small1</item>
-        <item name="android:backgroundTint">@color/settingslib_materialColorSecondaryContainer</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Icon.Filled.Large">
+        <item name="materialSizeOverlay">@style/SizeOverlay.Material3Expressive.Button.Medium</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Icon.Filled.Extra"
+        parent="@style/SettingsLibButtonStyle.Expressive.Icon.Filled.Large">
+        <item name="android:layout_width">match_parent</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Tonal"
+        parent="@style/Widget.Material3Expressive.Button.TonalButton.Icon">
+        <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">center</item>
         <item name="android:textAppearance">@style/TextAppearance.SettingsLib.LabelLarge</item>
-        <item name="android:textColor">@color/settingslib_materialColorOnSecondaryContainer</item>
-        <item name="iconGravity">textStart</item>
-        <item name="iconTint">@color/settingslib_materialColorOnSecondaryContainer</item>
-        <item name="iconSize">@dimen/settingslib_expressive_space_small4</item>
     </style>
 
     <style name="SettingsLibButtonStyle.Expressive.Tonal.Large">
-        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_small1</item>
-        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small4</item>
-        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.TitleMedium</item>
+        <item name="materialSizeOverlay">@style/SizeOverlay.Material3Expressive.Button.Medium</item>
     </style>
 
     <style name="SettingsLibButtonStyle.Expressive.Tonal.Extra"
@@ -74,29 +69,34 @@
         <item name="android:layout_width">match_parent</item>
     </style>
 
-    <style name="SettingsLibButtonStyle.Expressive.Outline"
-        parent="@style/Widget.Material3.Button.OutlinedButton.Icon">
+    <style name="SettingsLibButtonStyle.Expressive.Icon.Tonal"
+        parent="@style/Widget.Material3Expressive.Button.IconButton.Tonal">
         <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
         <item name="android:gravity">center</item>
-        <item name="android:minWidth">@dimen/settingslib_expressive_space_medium4</item>
-        <item name="android:minHeight">@dimen/settingslib_expressive_space_medium4</item>
-        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_extrasmall5</item>
-        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small1</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Icon.Tonal.Large">
+        <item name="materialSizeOverlay">@style/SizeOverlay.Material3Expressive.Button.Medium</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Icon.Tonal.Extra"
+        parent="@style/SettingsLibButtonStyle.Expressive.Tonal.Large">
+        <item name="android:layout_width">match_parent</item>
+    </style>
+
+    <style name="SettingsLibButtonStyle.Expressive.Outline"
+        parent="@style/Widget.Material3Expressive.Button.OutlinedButton.Icon">
+        <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">center</item>
         <item name="android:textAppearance">@style/TextAppearance.SettingsLib.LabelLarge</item>
-        <item name="android:textColor">@color/settingslib_materialColorPrimary</item>
-        <item name="iconTint">@color/settingslib_materialColorPrimary</item>
-        <item name="iconGravity">textStart</item>
-        <item name="iconSize">@dimen/settingslib_expressive_space_small4</item>
-        <item name="iconPadding">@dimen/settingslib_expressive_space_extrasmall4</item>
-        <item name="strokeColor">@color/settingslib_materialColorOutlineVariant</item>
     </style>
 
     <style name="SettingsLibButtonStyle.Expressive.Outline.Large">
-        <item name="android:paddingVertical">@dimen/settingslib_expressive_space_small1</item>
-        <item name="android:paddingHorizontal">@dimen/settingslib_expressive_space_small4</item>
-        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.TitleMedium</item>
+        <item name="materialSizeOverlay">@style/SizeOverlay.Material3Expressive.Button.Medium</item>
     </style>
 
     <style name="SettingsLibButtonStyle.Expressive.Outline.Extra"
@@ -105,15 +105,10 @@
     </style>
 
     <style name="SettingslibTextButtonStyle.Expressive"
-        parent="@style/Widget.Material3.Button.TextButton.Icon">
+        parent="@style/Widget.Material3Expressive.Button.TextButton.Icon">
         <item name="android:theme">@style/Theme.Material3.DynamicColors.DayNight</item>
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
-        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.BodyLarge.Emphasized</item>
-        <item name="android:textColor">@color/settingslib_materialColorOnSurface</item>
-        <item name="iconTint">@null</item>
-        <item name="iconPadding">@dimen/settingslib_expressive_space_extrasmall4</item>
-        <item name="rippleColor">?android:attr/colorControlHighlight</item>
     </style>
 
     <style name="SettingsLibCardStyle" parent="">
diff --git a/packages/SettingsLib/SettingsTheme/res/values/styles_m3_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values/styles_m3_expressive.xml
new file mode 100644
index 0000000..826fe31
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values/styles_m3_expressive.xml
@@ -0,0 +1,475 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 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.
+  -->
+
+<resources xmlns:tools="http://schemas.android.com/tools">
+    <!-- M3 Expressive filled button style. -->
+    <style name="Widget.Material3Expressive.Button" parent="Widget.Material3.Button">
+        <item name="android:paddingStart">?attr/containerPaddingStart</item>
+        <item name="android:paddingEnd">?attr/containerPaddingEnd</item>
+        <item name="android:paddingTop">?attr/containerPaddingTop</item>
+        <item name="android:paddingBottom">?attr/containerPaddingBottom</item>
+        <item name="android:insetTop">?attr/containerInsetTop</item>
+        <item name="android:insetBottom">?attr/containerInsetBottom</item>
+        <item name="iconPadding">?attr/containerIconPadding</item>
+        <item name="iconSize">?attr/containerIconSize</item>
+        <item name="android:textAppearance">?attr/labelTextAppearance</item>
+        <item name="shapeAppearance">@xml/settingslib_button_shape_state_list</item>
+        <item name="shapeAppearanceOverlay">@null</item>
+        <item name="materialThemeOverlay">@style/ThemeOverlay.Material3Expressive.Button.Filled</item>
+        <item name="materialSizeOverlay">@style/SizeOverlay.Material3Expressive.Button.Small</item>
+    </style>
+    <style name="Widget.Material3Expressive.Button.Icon"/>
+
+    <!-- M3 Expressive tonal button style. -->
+    <style name="Widget.Material3Expressive.Button.TonalButton">
+        <item name="materialThemeOverlay">@style/ThemeOverlay.Material3Expressive.Button.Tonal</item>
+    </style>
+    <style name="Widget.Material3Expressive.Button.TonalButton.Icon"/>
+
+    <!-- M3 Expressive outlined button style. -->
+    <style name="Widget.Material3Expressive.Button.OutlinedButton">
+        <item name="android:stateListAnimator" tools:ignore="NewApi">@animator/mtrl_btn_unelevated_state_list_anim</item>
+        <item name="elevation">0dp</item>
+        <item name="materialThemeOverlay">@style/ThemeOverlay.Material3Expressive.Button.Outlined</item>
+        <item name="strokeColor">@color/settingslib_expressive_button_outline_color_selector</item>
+        <item name="strokeWidth">?attr/containerStrokeWidth</item>
+        <item name="backgroundTint">@color/settingslib_expressive_button_outlined_background_color_selector</item>
+    </style>
+    <style name="Widget.Material3Expressive.Button.OutlinedButton.Icon"/>
+
+    <!-- M3 Expressive text button style. -->
+    <style name="Widget.Material3Expressive.Button.TextButton">
+        <item name="android:stateListAnimator" tools:ignore="NewApi">@animator/mtrl_btn_unelevated_state_list_anim</item>
+        <item name="elevation">0dp</item>
+        <item name="materialThemeOverlay">@style/ThemeOverlay.Material3Expressive.Button.TextButton</item>
+    </style>
+    <style name="Widget.Material3Expressive.Button.TextButton.Icon"/>
+
+    <!-- Styles for M3 Expressive Icon Buttons. -->
+
+    <!-- M3 Expressive icon only button without a container or outline style. -->
+    <style name="Widget.Material3Expressive.Button.IconButton">
+        <item name="android:stateListAnimator" tools:ignore="NewApi">@animator/mtrl_btn_unelevated_state_list_anim</item>
+        <item name="elevation">0dp</item>
+        <item name="android:minWidth">@dimen/settingslib_expressive_space_medium4</item>
+        <item name="android:minHeight">@dimen/settingslib_expressive_space_medium4</item>
+        <item name="android:insetLeft">?attr/containerInsetLeft</item>
+        <item name="android:insetRight">?attr/containerInsetRight</item>
+        <item name="iconPadding">@dimen/m3_btn_icon_only_icon_padding</item>
+        <item name="materialThemeOverlay">@style/ThemeOverlay.Material3Expressive.Button.IconButton.Standard</item>
+        <item name="materialSizeOverlay">@style/SizeOverlay.Material3Expressive.Button.IconButton.Small</item>
+    </style>
+
+    <!-- M3 Expressive icon only button filled container style. -->
+    <style name="Widget.Material3Expressive.Button.IconButton.Filled">
+        <item name="materialThemeOverlay">@style/ThemeOverlay.Material3Expressive.Button.Filled</item>
+    </style>
+
+    <!-- M3 Expressive icon only button in tonal container style. -->
+    <style name="Widget.Material3Expressive.Button.IconButton.Tonal">
+        <item name="materialThemeOverlay">@style/ThemeOverlay.Material3Expressive.Button.Tonal</item>
+    </style>
+
+    <!-- M3 Expressive icon only button with an outline style. -->
+    <style name="Widget.Material3Expressive.Button.IconButton.Outlined">
+        <item name="materialThemeOverlay">@style/ThemeOverlay.Material3Expressive.Button.Outlined</item>
+        <item name="strokeColor">@color/settingslib_expressive_button_outline_color_selector</item>
+        <item name="strokeWidth">?attr/containerStrokeWidth</item>
+        <item name="backgroundTint">@color/settingslib_expressive_button_outlined_background_color_selector</item>
+    </style>
+
+    <!-- Styles for M3 Expressive Button Groups. -->
+
+    <!-- M3 Expressive Button Group. -->
+    <style name="Widget.Material3Expressive.MaterialButtonGroup" parent="Widget.Material3.MaterialButtonGroup"/>
+
+    <!-- M3 Expressive Connected Button Group. -->
+    <style name="Widget.Material3Expressive.MaterialButtonGroup.Connected" parent="Widget.Material3.MaterialButtonGroup.Connected">
+        <item name="innerCornerSize">@xml/settingslib_inner_corner_size_state_list</item>
+    </style>
+
+    <!-- M3 Expressive Button Toggle Group (Segmented Button). -->
+    <style name="Widget.Material3Expressive.MaterialButtonToggleGroup" parent="Widget.Material3.MaterialButtonToggleGroup">
+        <item name="innerCornerSize">@xml/settingslib_inner_corner_size_state_list</item>
+        <item name="shapeAppearance">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="android:spacing">@dimen/settingslib_expressive_space_extrasmall1</item>
+    </style>
+
+    <!-- M3 Expressive Button Theme Overlays for different color variants. -->
+
+    <!-- M3 Expressive Button Theme Overlay for the filled color variant. -->
+    <style name="ThemeOverlay.Material3Expressive.Button.Filled" parent="">
+        <item name="colorContainer">?attr/colorPrimary</item>
+        <item name="colorContainerChecked">?attr/colorPrimary</item>
+        <item name="colorContainerUnchecked">?attr/colorSurfaceContainer</item>
+        <item name="colorOnContainer">?attr/colorOnPrimary</item>
+        <item name="colorOnContainerChecked">?attr/colorOnPrimary</item>
+        <item name="colorOnContainerUnchecked">?attr/colorOnSurfaceVariant</item>
+    </style>
+
+    <!-- M3 Expressive Button Theme Overlay for the tonal color variant. -->
+    <style name="ThemeOverlay.Material3Expressive.Button.Tonal" parent="">
+        <item name="colorContainer">?attr/colorSecondaryContainer</item>
+        <item name="colorContainerChecked">?attr/colorSecondary</item>
+        <item name="colorContainerUnchecked">?attr/colorSecondaryContainer</item>
+        <item name="colorOnContainer">?attr/colorOnSecondaryContainer</item>
+        <item name="colorOnContainerChecked">?attr/colorOnSecondary</item>
+        <item name="colorOnContainerUnchecked">?attr/colorOnSecondaryContainer</item>
+    </style>
+
+    <!-- M3 Expressive Button Theme Overlay for the outlined variant. -->
+    <style name="ThemeOverlay.Material3Expressive.Button.Outlined" parent="">
+        <item name="colorContainer">@android:color/transparent</item>
+        <item name="colorContainerChecked">?attr/colorSurfaceInverse</item>
+        <item name="colorContainerUnchecked">@android:color/transparent</item>
+        <item name="colorOnContainer">?attr/colorOnSurfaceVariant</item>
+        <item name="colorOnContainerChecked">?attr/colorOnSurfaceInverse</item>
+        <item name="colorOnContainerUnchecked">?attr/colorOnSurfaceVariant</item>
+    </style>
+
+    <!-- M3 Expressive Button Theme Overlay for the text only variant. -->
+    <style name="ThemeOverlay.Material3Expressive.Button.TextButton" parent="ThemeOverlay.Material3.Button.TextButton">
+        <item name="colorContainerChecked">?attr/colorContainer</item>
+        <item name="colorContainerUnchecked">?attr/colorContainer</item>
+        <item name="colorOnContainerChecked">?attr/colorOnContainer</item>
+        <item name="colorOnContainerUnchecked">?attr/colorOnSurfaceVariant</item>
+    </style>
+
+    <!-- M3 Expressive Button Theme Overlay for the icon only variant. -->
+    <style name="ThemeOverlay.Material3Expressive.Button.IconButton.Standard" parent="">
+        <item name="colorContainer">@android:color/transparent</item>
+        <item name="colorContainerChecked">@android:color/transparent</item>
+        <item name="colorContainerUnchecked">@android:color/transparent</item>
+        <item name="colorOnContainer">?attr/colorOnSurfaceVariant</item>
+        <item name="colorOnContainerChecked">?attr/colorPrimary</item>
+        <item name="colorOnContainerUnchecked">?attr/colorOnSurfaceVariant</item>
+    </style>
+
+    <!-- M3 Expressive Button Theme Overlay for the extra small variant. -->
+    <style name="SizeOverlay.Material3Expressive.Button.Xsmall" parent="">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_extrasmall6</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_extrasmall6</item>
+        <item name="containerPaddingTop">6dp</item>
+        <item name="containerPaddingBottom">6dp</item>
+        <item name="containerInsetTop">8dp</item>
+        <item name="containerInsetBottom">8dp</item>
+        <item name="containerIconSize">@dimen/settingslib_expressive_space_small3</item>
+        <item name="containerIconPadding">@dimen/settingslib_expressive_space_extrasmall4</item>
+        <item name="containerStrokeWidth">1dp</item>
+        <item name="labelTextAppearance">?attr/textAppearanceLabelLarge</item>
+        <item name="containerShapePressed">?attr/shapeAppearanceCornerSmall</item>
+        <item name="containerShapeChecked">?attr/shapeAppearanceCornerMedium</item>
+        <item name="containerShapeDefault">@style/ShapeAppearance.Material3.Corner.Full</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.Xsmall.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerMedium</item>
+    </style>
+
+    <!-- M3 Expressive Button Theme Overlay for the small variant. -->
+    <style name="SizeOverlay.Material3Expressive.Button.Small" parent="">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_small1</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_small1</item>
+        <item name="containerPaddingTop">10dp</item>
+        <item name="containerPaddingBottom">10dp</item>
+        <item name="containerInsetTop">4dp</item>
+        <item name="containerInsetBottom">4dp</item>
+        <item name="containerIconSize">@dimen/settingslib_expressive_space_small3</item>
+        <item name="containerIconPadding">@dimen/settingslib_expressive_space_extrasmall4</item>
+        <item name="containerStrokeWidth">1dp</item>
+        <item name="labelTextAppearance">?attr/textAppearanceLabelLarge</item>
+        <item name="containerShapePressed">?attr/shapeAppearanceCornerSmall</item>
+        <item name="containerShapeChecked">?attr/shapeAppearanceCornerMedium</item>
+        <item name="containerShapeDefault">@style/ShapeAppearance.Material3.Corner.Full</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.Small.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerMedium</item>
+    </style>
+
+    <!-- M3 Expressive Button Theme Overlay for the medium variant. -->
+    <style name="SizeOverlay.Material3Expressive.Button.Medium" parent="">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_small4</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_small4</item>
+        <item name="containerPaddingTop">16dp</item>
+        <item name="containerPaddingBottom">16dp</item>
+        <item name="containerInsetTop">0dp</item>
+        <item name="containerInsetBottom">0dp</item>
+        <item name="containerIconSize">@dimen/settingslib_expressive_space_small4</item>
+        <item name="containerIconPadding">@dimen/settingslib_expressive_space_extrasmall4</item>
+        <item name="containerStrokeWidth">1dp</item>
+        <item name="labelTextAppearance">?attr/textAppearanceTitleMedium</item>
+        <item name="containerShapePressed">?attr/shapeAppearanceCornerMedium</item>
+        <item name="containerShapeChecked">?attr/shapeAppearanceCornerLarge</item>
+        <item name="containerShapeDefault">@style/ShapeAppearance.Material3.Corner.Full</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.Medium.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerLarge</item>
+    </style>
+
+    <!-- M3 Expressive Button Theme Overlay for the large variant. -->
+    <style name="SizeOverlay.Material3Expressive.Button.Large" parent="">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_medium4</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_medium4</item>
+        <item name="containerPaddingTop">32dp</item>
+        <item name="containerPaddingBottom">32dp</item>
+        <item name="containerInsetTop">0dp</item>
+        <item name="containerInsetBottom">0dp</item>
+        <item name="containerIconSize">@dimen/settingslib_expressive_space_medium1</item>
+        <item name="containerIconPadding">@dimen/settingslib_expressive_space_extrasmall6</item>
+        <item name="containerStrokeWidth">@dimen/settingslib_expressive_space_extrasmall1</item>
+        <item name="labelTextAppearance">?attr/textAppearanceHeadlineSmall</item>
+        <item name="containerShapePressed">?attr/shapeAppearanceCornerLarge</item>
+        <item name="containerShapeChecked">?attr/shapeAppearanceCornerExtraLarge</item>
+        <item name="containerShapeDefault">@style/ShapeAppearance.Material3.Corner.Full</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.Large.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerExtraLarge</item>
+    </style>
+
+    <!-- M3 Expressive Button Theme Overlay for the extra large variant. -->
+    <style name="SizeOverlay.Material3Expressive.Button.Xlarge" parent="">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_large2</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_large2</item>
+        <item name="containerPaddingTop">48dp</item>
+        <item name="containerPaddingBottom">48dp</item>
+        <item name="containerInsetTop">0dp</item>
+        <item name="containerInsetBottom">0dp</item>
+        <item name="containerIconSize">@dimen/settingslib_expressive_space_medium3</item>
+        <item name="containerIconPadding">@dimen/settingslib_expressive_space_small1</item>
+        <item name="containerStrokeWidth">3dp</item>
+        <item name="labelTextAppearance">?attr/textAppearanceHeadlineLarge</item>
+        <item name="containerShapePressed">?attr/shapeAppearanceCornerLarge</item>
+        <item name="containerShapeChecked">?attr/shapeAppearanceCornerExtraLarge</item>
+        <item name="containerShapeDefault">@style/ShapeAppearance.Material3.Corner.Full</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.Xlarge.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerExtraLarge</item>
+    </style>
+
+    <!-- M3 Expressive Icon Button Theme Overlay for the extra small variant. -->
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Xsmall" parent="">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_extrasmall3</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_extrasmall3</item>
+        <item name="containerPaddingTop">6dp</item>
+        <item name="containerPaddingBottom">6dp</item>
+        <item name="containerInsetTop">8dp</item>
+        <item name="containerInsetBottom">8dp</item>
+        <item name="containerInsetLeft">8dp</item>
+        <item name="containerInsetRight">8dp</item>
+        <item name="containerIconSize">@dimen/settingslib_expressive_space_small3</item>
+        <item name="containerStrokeWidth">1dp</item>
+        <item name="containerShapePressed">?attr/shapeAppearanceCornerSmall</item>
+        <item name="containerShapeChecked">?attr/shapeAppearanceCornerMedium</item>
+        <item name="containerShapeDefault">@style/ShapeAppearance.Material3.Corner.Full</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Xsmall.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerMedium</item>
+    </style>
+
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Xsmall.Narrow">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_extrasmall2</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_extrasmall2</item>
+        <item name="containerInsetLeft">10dp</item>
+        <item name="containerInsetRight">10dp</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Xsmall.Narrow.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerMedium</item>
+    </style>
+
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Xsmall.Wide">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_extrasmall5</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_extrasmall5</item>
+        <item name="containerInsetLeft">4dp</item>
+        <item name="containerInsetRight">4dp</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Xsmall.Wide.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerMedium</item>
+    </style>
+
+    <!-- M3 Expressive Icon Button Theme Overlay for the small variant. -->
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Small" parent="">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_extrasmall4</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_extrasmall4</item>
+        <item name="containerPaddingTop">8dp</item>
+        <item name="containerPaddingBottom">8dp</item>
+        <item name="containerInsetTop">4dp</item>
+        <item name="containerInsetBottom">4dp</item>
+        <item name="containerInsetLeft">4dp</item>
+        <item name="containerInsetRight">4dp</item>
+        <item name="containerIconSize">@dimen/settingslib_expressive_space_small4</item>
+        <item name="containerStrokeWidth">1dp</item>
+        <item name="containerShapePressed">?attr/shapeAppearanceCornerSmall</item>
+        <item name="containerShapeChecked">?attr/shapeAppearanceCornerMedium</item>
+        <item name="containerShapeDefault">@style/ShapeAppearance.Material3.Corner.Full</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Small.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerMedium</item>
+    </style>
+
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Small.Narrow">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_extrasmall2</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_extrasmall2</item>
+        <item name="containerInsetLeft">8dp</item>
+        <item name="containerInsetRight">8dp</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Small.Narrow.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerMedium</item>
+    </style>
+
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Small.Wide">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_extrasmall7</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_extrasmall7</item>
+        <item name="containerInsetLeft">0dp</item>
+        <item name="containerInsetRight">0dp</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Small.Wide.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerMedium</item>
+    </style>
+
+    <!-- M3 Expressive Icon Button Theme Overlay for the medium variant. -->
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Medium" parent="">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_small1</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_small1</item>
+        <item name="containerPaddingTop">16dp</item>
+        <item name="containerPaddingBottom">16dp</item>
+        <item name="containerInsetTop">0dp</item>
+        <item name="containerInsetBottom">0dp</item>
+        <item name="containerInsetLeft">0dp</item>
+        <item name="containerInsetRight">0dp</item>
+        <item name="containerIconSize">@dimen/settingslib_expressive_space_small4</item>
+        <item name="containerStrokeWidth">1dp</item>
+        <item name="containerShapePressed">?attr/shapeAppearanceCornerMedium</item>
+        <item name="containerShapeChecked">?attr/shapeAppearanceCornerLarge</item>
+        <item name="containerShapeDefault">@style/ShapeAppearance.Material3.Corner.Full</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Medium.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerLarge</item>
+    </style>
+
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Medium.Narrow">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_extrasmall6</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_extrasmall6</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Medium.Narrow.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerLarge</item>
+    </style>
+
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Medium.Wide">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_small4</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_small4</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Medium.Wide.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerLarge</item>
+    </style>
+
+    <!-- M3 Expressive Icon Button Theme Overlay for the large variant. -->
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Large" parent="">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_medium1</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_medium1</item>
+        <item name="containerPaddingTop">32dp</item>
+        <item name="containerPaddingBottom">32dp</item>
+        <item name="containerInsetTop">0dp</item>
+        <item name="containerInsetBottom">0dp</item>
+        <item name="containerInsetLeft">0dp</item>
+        <item name="containerInsetRight">0dp</item>
+        <item name="containerIconSize">@dimen/settingslib_expressive_space_medium1</item>
+        <item name="containerStrokeWidth">@dimen/settingslib_expressive_space_extrasmall1</item>
+        <item name="containerShapePressed">?attr/shapeAppearanceCornerLarge</item>
+        <item name="containerShapeChecked">?attr/shapeAppearanceCornerExtraLarge</item>
+        <item name="containerShapeDefault">@style/ShapeAppearance.Material3.Corner.Full</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Large.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerExtraLarge</item>
+    </style>
+
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Large.Narrow">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_small1</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_small1</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Large.Narrow.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerExtraLarge</item>
+    </style>
+
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Large.Wide">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_medium4</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_medium4</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Large.Wide.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerExtraLarge</item>
+    </style>
+
+    <!-- M3 Expressive Icon Button Theme Overlay for the extra large variant. -->
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Xlarge" parent="">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_medium4</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_medium4</item>
+        <item name="containerPaddingTop">48dp</item>
+        <item name="containerPaddingBottom">48dp</item>
+        <item name="containerInsetTop">0dp</item>
+        <item name="containerInsetBottom">0dp</item>
+        <item name="containerInsetLeft">0dp</item>
+        <item name="containerInsetRight">0dp</item>
+        <item name="containerIconSize">@dimen/settingslib_expressive_space_medium3</item>
+        <item name="containerStrokeWidth">3dp</item>
+        <item name="containerShapePressed">?attr/shapeAppearanceCornerLarge</item>
+        <item name="containerShapeChecked">?attr/shapeAppearanceCornerExtraLarge</item>
+        <item name="containerShapeDefault">@style/ShapeAppearance.Material3.Corner.Full</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Xlarge.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerExtraLarge</item>
+    </style>
+
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Xlarge.Narrow">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_medium1</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_medium1</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Xlarge.Narrow.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerExtraLarge</item>
+    </style>
+
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Xlarge.Wide">
+        <item name="containerPaddingStart">@dimen/settingslib_expressive_space_large3</item>
+        <item name="containerPaddingEnd">@dimen/settingslib_expressive_space_large3</item>
+    </style>
+    <style name="SizeOverlay.Material3Expressive.Button.IconButton.Xlarge.Wide.Square">
+        <item name="containerShapeChecked">@style/ShapeAppearance.Material3.Corner.Full</item>
+        <item name="containerShapeDefault">?attr/shapeAppearanceCornerExtraLarge</item>
+    </style>
+
+    <!-- M3 shape -->
+    <style name="ShapeAppearance.Material3.Corner.Full" parent="">
+        <item name="cornerFamily">?attr/shapeCornerFamily</item>
+        <item name="cornerSize">50%</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/xml/settingslib_button_shape_state_list.xml b/packages/SettingsLib/SettingsTheme/res/xml/settingslib_button_shape_state_list.xml
new file mode 100644
index 0000000..defedb3
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/xml/settingslib_button_shape_state_list.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item android:state_checkable="true" android:state_pressed="true"
+        app:shapeAppearance="?attr/containerShapePressed"/>
+    <item android:state_checked="true"
+        app:shapeAppearance="?attr/containerShapeChecked"/>
+    <item app:shapeAppearance="?attr/containerShapeDefault"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/xml/settingslib_inner_corner_size_state_list.xml b/packages/SettingsLib/SettingsTheme/res/xml/settingslib_inner_corner_size_state_list.xml
new file mode 100644
index 0000000..6e49c7c
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/xml/settingslib_inner_corner_size_state_list.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item android:state_checkable="true" android:state_pressed="true"
+        app:cornerSize="4dp"/>
+    <item android:state_checked="true"
+        app:cornerSize="50%"/>
+    <item app:cornerSize="8dp"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SliderPreference/src/com/android/settingslib/widget/SliderPreference.java b/packages/SettingsLib/SliderPreference/src/com/android/settingslib/widget/SliderPreference.java
index 1815d04..4315238 100644
--- a/packages/SettingsLib/SliderPreference/src/com/android/settingslib/widget/SliderPreference.java
+++ b/packages/SettingsLib/SliderPreference/src/com/android/settingslib/widget/SliderPreference.java
@@ -268,7 +268,9 @@
         mSlider.setValueFrom(mMin);
         mSlider.setValueTo(mMax);
         mSlider.setValue(mSliderValue);
+        mSlider.clearOnSliderTouchListeners();
         mSlider.addOnSliderTouchListener(mTouchListener);
+        mSlider.clearOnChangeListeners();
         mSlider.addOnChangeListener(mChangeListener);
         mSlider.setEnabled(isEnabled());
 
@@ -487,7 +489,7 @@
      * set the {@link Slider}'s value to the stored value.
      */
     void syncValueInternal(@NonNull Slider slider) {
-        int sliderValue = mMin + (int) slider.getValue();
+        int sliderValue = (int) slider.getValue();
         if (sliderValue != mSliderValue) {
             if (callChangeListener(sliderValue)) {
                 setValueInternal(sliderValue, false);
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt
index fcaedd2..a52222b 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt
@@ -64,7 +64,7 @@
         bottom = itemPaddingVertical,
     )
     val itemPaddingAround = 8.dp
-    val itemDividerHeight = 32.dp
+    val itemDividerHeight = if (isSpaExpressiveEnabled) 40.dp else 32.dp
 
     val iconLarge = 48.dp
     val introIconSize = 40.dp
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetPreference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetPreference.kt
index 3aa7ad0..8b1ed93 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetPreference.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/TwoTargetPreference.kt
@@ -28,8 +28,6 @@
 import androidx.compose.material3.Icon
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
@@ -104,8 +102,17 @@
 @Composable
 private fun PreferenceDivider() {
     Box(
-        Modifier.padding(horizontal = SettingsDimension.itemPaddingEnd)
-            .size(width = 1.dp, height = SettingsDimension.itemDividerHeight)
-            .background(color = MaterialTheme.colorScheme.divider)
+        if (isSpaExpressiveEnabled) {
+            Modifier.padding(
+                    start = SettingsDimension.paddingSmall,
+                    end = SettingsDimension.paddingExtraSmall6,
+                )
+                .size(width = 1.dp, height = SettingsDimension.itemDividerHeight)
+                .background(color = MaterialTheme.colorScheme.outline)
+        } else {
+            Modifier.padding(horizontal = SettingsDimension.itemPaddingEnd)
+                .size(width = 1.dp, height = SettingsDimension.itemDividerHeight)
+                .background(color = MaterialTheme.colorScheme.divider)
+        }
     )
 }
diff --git a/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/FlowTestUtil.kt b/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/FlowTestUtil.kt
index 99c6a3f..591dff7 100644
--- a/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/FlowTestUtil.kt
+++ b/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/FlowTestUtil.kt
@@ -17,18 +17,50 @@
 package com.android.settingslib.spa.testutils
 
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.firstOrNull
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.withTimeoutOrNull
 
+/**
+ * Collects the first element emitted by this flow within a given timeout.
+ *
+ * If the flow emits a value within the given timeout, this function returns that value. If the
+ * timeout expires before the flow emits any values, this function returns null.
+ *
+ * This function is similar to [kotlinx.coroutines.flow.firstOrNull], but it adds a timeout to
+ * prevent potentially infinite waiting.
+ *
+ * @param timeMillis The timeout in milliseconds. Defaults to 500 milliseconds.
+ * @return The first element emitted by the flow within the timeout, or null if the timeout expires.
+ */
 suspend fun <T> Flow<T>.firstWithTimeoutOrNull(timeMillis: Long = 500): T? =
-    withTimeoutOrNull(timeMillis) {
-        first()
-    }
+    withTimeoutOrNull(timeMillis) { firstOrNull() }
 
-suspend fun <T> Flow<T>.toListWithTimeout(timeMillis: Long = 500): List<T> {
-    val list = mutableListOf<T>()
-    return withTimeoutOrNull(timeMillis) {
-        toList(list)
-    } ?: list
+/**
+ * Collects elements from this flow for a given time and returns the last emitted element, or null
+ * if the flow did not emit any elements.
+ *
+ * This function is useful when you need to retrieve the last value emitted by a flow within a
+ * specific timeframe, but the flow might complete without emitting anything or might not emit a
+ * value within the given timeout.
+ *
+ * @param timeMillis The timeout in milliseconds. Defaults to 500ms.
+ * @return The last emitted element, or null if the flow did not emit any elements.
+ */
+suspend fun <T> Flow<T>.lastWithTimeoutOrNull(timeMillis: Long = 500): T? =
+    toListWithTimeout(timeMillis).lastOrNull()
+
+/**
+ * Collects elements from this flow into a list with a timeout.
+ *
+ * This function attempts to collect all elements from the flow and store them in a list. If the
+ * collection process takes longer than the specified timeout, the collection is canceled and the
+ * function returns the elements collected up to that point.
+ *
+ * @param timeMillis The timeout duration in milliseconds. Defaults to 500 milliseconds.
+ * @return A list containing the collected elements, or an empty list if the timeout was reached
+ *   before any elements were collected.
+ */
+suspend fun <T> Flow<T>.toListWithTimeout(timeMillis: Long = 500): List<T> = buildList {
+    withTimeoutOrNull(timeMillis) { toList(this@buildList) }
 }
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUser.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUser.kt
index 7d6ee19..60ef733 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUser.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUser.kt
@@ -21,9 +21,8 @@
 import android.content.IntentFilter
 import android.os.UserHandle
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalLifecycleOwner
-import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
 import com.android.settingslib.spaprivileged.framework.common.broadcastReceiverAsUserFlow
 
 /**
@@ -35,6 +34,8 @@
     userHandle: UserHandle,
     onReceive: (Intent) -> Unit,
 ) {
-    LocalContext.current.broadcastReceiverAsUserFlow(intentFilter, userHandle)
-        .collectLatestWithLifecycle(LocalLifecycleOwner.current, action = onReceive)
+    val context = LocalContext.current
+    LaunchedEffect(Unit) {
+        context.broadcastReceiverAsUserFlow(intentFilter, userHandle).collect(onReceive)
+    }
 }
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt
index a59a724..4221f9f 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt
@@ -22,10 +22,11 @@
 import android.content.IntentFilter
 import android.os.UserHandle
 import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.lifecycle.compose.LocalLifecycleOwner
-import androidx.lifecycle.testing.TestLifecycleOwner
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import org.junit.Rule
 import org.junit.Test
@@ -38,34 +39,39 @@
 
 @RunWith(AndroidJUnit4::class)
 class DisposableBroadcastReceiverAsUserTest {
-    @get:Rule
-    val composeTestRule = createComposeRule()
+    @get:Rule val composeTestRule = createComposeRule()
 
     private var registeredBroadcastReceiver: BroadcastReceiver? = null
 
-    private val context = mock<Context> {
-        on {
-            registerReceiverAsUser(
-                any(),
-                eq(USER_HANDLE),
-                eq(INTENT_FILTER),
-                isNull(),
-                isNull(),
-                eq(Context.RECEIVER_NOT_EXPORTED),
-            )
-        } doAnswer {
-            registeredBroadcastReceiver = it.arguments[0] as BroadcastReceiver
-            null
+    private val context =
+        mock<Context> {
+            on {
+                registerReceiverAsUser(
+                    any(),
+                    eq(USER_HANDLE),
+                    eq(INTENT_FILTER),
+                    isNull(),
+                    isNull(),
+                    eq(Context.RECEIVER_NOT_EXPORTED),
+                )
+            } doAnswer
+                {
+                    registeredBroadcastReceiver = it.arguments[0] as BroadcastReceiver
+                    null
+                }
+
+            on { unregisterReceiver(any()) } doAnswer
+                {
+                    if (registeredBroadcastReceiver === it.arguments[0]) {
+                        registeredBroadcastReceiver = null
+                    }
+                }
         }
-    }
 
     @Test
     fun broadcastReceiver_registered() {
         composeTestRule.setContent {
-            CompositionLocalProvider(
-                LocalContext provides context,
-                LocalLifecycleOwner provides TestLifecycleOwner(),
-            ) {
+            CompositionLocalProvider(LocalContext provides context) {
                 DisposableBroadcastReceiverAsUser(INTENT_FILTER, USER_HANDLE) {}
             }
         }
@@ -77,10 +83,7 @@
     fun broadcastReceiver_isCalledOnReceive() {
         var onReceiveIsCalled = false
         composeTestRule.setContent {
-            CompositionLocalProvider(
-                LocalContext provides context,
-                LocalLifecycleOwner provides TestLifecycleOwner(),
-            ) {
+            CompositionLocalProvider(LocalContext provides context) {
                 DisposableBroadcastReceiverAsUser(INTENT_FILTER, USER_HANDLE) {
                     onReceiveIsCalled = true
                 }
@@ -92,6 +95,23 @@
         composeTestRule.waitUntil { onReceiveIsCalled }
     }
 
+    @Test
+    fun broadcastReceiver_unregistered() {
+        var isBroadcastReceiverRegistered by mutableStateOf(true)
+        composeTestRule.setContent {
+            if (isBroadcastReceiverRegistered) {
+                CompositionLocalProvider(LocalContext provides context) {
+                    DisposableBroadcastReceiverAsUser(INTENT_FILTER, USER_HANDLE) {}
+                }
+            }
+        }
+        composeTestRule.waitUntil { registeredBroadcastReceiver != null }
+
+        isBroadcastReceiverRegistered = false
+
+        composeTestRule.waitUntil { registeredBroadcastReceiver == null }
+    }
+
     private companion object {
         val USER_HANDLE: UserHandle = UserHandle.of(0)
 
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/PermissionsChangedFlowTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/PermissionsChangedFlowTest.kt
index 31522c12..7ef11eb 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/PermissionsChangedFlowTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/PermissionsChangedFlowTest.kt
@@ -23,7 +23,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
 import com.android.settingslib.spa.testutils.toListWithTimeout
-import com.android.settingslib.spaprivileged.framework.common.asUser
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.async
 import kotlinx.coroutines.delay
@@ -35,6 +34,7 @@
 import org.mockito.kotlin.doReturn
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.spy
+import org.mockito.kotlin.whenever
 
 @RunWith(AndroidJUnit4::class)
 class PermissionsChangedFlowTest {
@@ -49,7 +49,7 @@
     }
 
     private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
-        on { asUser(APP.userHandle) } doReturn mock
+        doReturn(mock).whenever(mock).createContextAsUser(APP.userHandle, 0)
         on { packageManager } doReturn mockPackageManager
     }
 
diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml
index 6dd8fef..e4eb72d 100644
--- a/packages/SettingsLib/res/values-af/arrays.xml
+++ b/packages/SettingsLib/res/values-af/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Slegs toestelskerm (verstek)"</item>
+    <item msgid="9161645858025071955">"Eksterne skerm"</item>
+    <item msgid="114384731934682483">"Fokusgebaseer"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Wys skakering net op toestelskerm"</item>
+    <item msgid="7795034287069726554">"Wys skerm op enkele eksterne skerm"</item>
+    <item msgid="5280431949814340475">"Wys toestel op laaste gefokusde skerm"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 9af8ba8..7e9e369 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktief (net links)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktief (net regs)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktief (links en regs)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktief (net media). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiewe (net media). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Gekoppel (steun oudiodeling). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Oorganganimasieskaal"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator-tydsduurskaal"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simuleer sekondêre uitstallings"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Skakeringskermposisie"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Moenie aktiwiteite behou nie"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Vernietig elke aktiwiteit sodra die gebruiker dit verlaat"</string>
diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml
index 2a05261..805f0d3 100644
--- a/packages/SettingsLib/res/values-am/arrays.xml
+++ b/packages/SettingsLib/res/values-am/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"የመሣሪያ ማሳያ ብቻ (ነባሪ)"</item>
+    <item msgid="9161645858025071955">"ውጫዊ ማሳያ"</item>
+    <item msgid="114384731934682483">"ትኩረት ላይ የተመሰረተ"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"በመሣሪያ ማሳያ ላይ ብቻ ጥላ አሳይ"</item>
+    <item msgid="7795034287069726554">"መሣሪያን በአንድ ውጫዊ ማሳያ ላይ አሳይ"</item>
+    <item msgid="5280431949814340475">"በመጨረሻ ትኩረት የተደረገበት ማሳያ ላይ መሣሪያን አሳይ"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 03cde01..6161873 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"ገቢር (ግራ ብቻ)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"ገቢር (ቀኝ ብቻ)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"ገቢር (ግራ እና ቀኝ)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ገቢር (ሚዲያ ብቻ)። <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ባትሪ።"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ገቢር (ሚዲያ ብቻ)። ግ፦ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>፣ ቀ፦ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ባትሪ።"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"ተገናኝቷል (የድምፅ ማጋራት ይደግፋል)፣ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ባትሪ።"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"የእነማ ልኬት ለውጥ ሽግግር"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"እነማ አድራጊ ቆይታ መለኪያ"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"ሁለተኛ ማሳያዎችን አስመስለህ ሥራ"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"የጥላ ማሳያ አቀማመጥ"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"መተግበሪያዎች"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"እንቅስቃሴዎችን አትጠብቅ"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ተጠቃሚው እስኪተወው ድረስ እያንዳንዱን እንቅስቃሴ አስወግድ"</string>
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index f389f64..3ff5dc6 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"شاشة الجهاز فقط (الإعداد التلقائي)"</item>
+    <item msgid="9161645858025071955">"الشاشة الخارجية"</item>
+    <item msgid="114384731934682483">"على الشاشة التي يتم التركيز عليها"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"عرض الظل على شاشة الجهاز فقط"</item>
+    <item msgid="7795034287069726554">"عرض الظل على شاشة خارجية واحدة"</item>
+    <item msgid="5280431949814340475">"عرض الظل على آخر شاشة تم التركيز عليها"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 87a8241..a298294 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"سماعة الأذن الطبية نشطة (اليسرى فقط)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"سماعة الأذن الطبية نشطة (اليمنى فقط)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"سماعتا الأذن الطبيتان نشطتان (اليسرى واليمنى)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"‏البلوتوث نشِط (للوسائط فقط). مستوى شحن البطارية: ‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"‏البلوتوث نشِط (للوسائط فقط)، مستوى الشحن في سماعة الرأس اليسرى: ‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>، مستوى الشحن في سماعة الرأس اليمنى: ‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"‏البلوتوث متصل (ميزة \"مشاركة الصوت\" متاحة). مستوى شحن البطارية: ‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"حجم الرسوم المتحركة للنقل"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"طول مدة الرسوم المتحركة"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"محاكاة الشاشات الثانوية"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"موضع شاشة عرض الظل"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"التطبيقات"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"عدم الاحتفاظ بالأنشطة"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"محو كل نشاط فور مغادرة المستخدم له"</string>
diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml
index b5dfde5..4b5d5a0 100644
--- a/packages/SettingsLib/res/values-as/arrays.xml
+++ b/packages/SettingsLib/res/values-as/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"কেৱল ডিভাইচৰ ডিছপ্লে’ (ডিফ’ল্ট)"</item>
+    <item msgid="9161645858025071955">"বাহ্যিক ডিছপ্লে’"</item>
+    <item msgid="114384731934682483">"ফ’কাছ-আধাৰিত"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"কেৱল ডিভাইচৰ ডিছপ্লে’তহে শ্বেড দেখুৱাওক"</item>
+    <item msgid="7795034287069726554">"ডিভাইচটো এখনেই বাহ্যিক ডিছপ্লে’ত দেখুৱাওক"</item>
+    <item msgid="5280431949814340475">"ডিভাইচটো অন্তিম ফ’কাছ কৰা ডিছপ্লে’ত দেখুৱাওক"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 4aab7d6..addf12b 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"সক্ৰিয় হৈ আছে (কেৱল বাওঁফালৰটো)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"সক্ৰিয় হৈ আছে (কেৱল সোঁফালৰটো)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"সক্ৰিয় হৈ আছে (বাওঁফালৰটো আৰু সোঁফালৰটো)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"সক্ৰিয় হৈ আছে (কেৱল মিডিয়া)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰী।"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"সক্ৰিয় হৈ আছে (কেৱল মিডিয়া)। বাওঁ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, সোঁ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> বেটাৰী।"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"সংযুক্ত হৈ আছে (অডিঅ’ শ্বেয়াৰিং সমৰ্থন কৰে), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> বেটাৰী।"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ট্ৰাঞ্জিশ্বন এনিমেশ্বন স্কেল"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"এনিমেটৰ কালদৈৰ্ঘ্য স্কেল"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"গৌণ প্ৰদৰ্শনৰ নকল বনাওক"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"শ্বেড ডিছপ্লে’ৰ স্থান"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"এপ্‌সমূহ"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"কাৰ্যকলাপসমূহ নাৰাখিব"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ব্যৱহাৰকাৰী ওলোৱাৰ লগে লগে আটাইবোৰ কাৰ্যকলাপ মচক"</string>
diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml
index 4f7aabd..511e970 100644
--- a/packages/SettingsLib/res/values-az/arrays.xml
+++ b/packages/SettingsLib/res/values-az/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Yalnız cihaz displeyi (defolt)"</item>
+    <item msgid="9161645858025071955">"Xarici displey"</item>
+    <item msgid="114384731934682483">"Fokus əsaslı"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Kölgəni yalnız cihaz displeyində göstərin"</item>
+    <item msgid="7795034287069726554">"Cihazı bir xarici displeydə göstərin"</item>
+    <item msgid="5280431949814340475">"Cihazı son fokuslanmış displeydə göstərin"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 5841bda..6f97c9c 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktiv (yalnız sol)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktiv (yalnız sağ)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktiv (sol və sağ)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiv (yalnız media). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiv (yalnız media). Sol: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Sağ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batareya."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Qoşulub (audio paylaşma dəstəklənir). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batareya."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Keçid animasiyası"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animasiya müddəti"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"İkincili displeyi imitasiya edin"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Kölgənin ekran mövqeyi"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Tətbiqlər"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Fəaliyyətlər saxlanmasın"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"İstifadəçi çıxan kimi fəaliyyət silinsin"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
index f5ba2df..4528314 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Prikaz samo na uređaju (podrazumevano)"</item>
+    <item msgid="9161645858025071955">"Spoljni ekran"</item>
+    <item msgid="114384731934682483">"Zasnovano na fokusu"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Prikaži senku samo na ekranu uređaja"</item>
+    <item msgid="7795034287069726554">"Prikaži uređaj na jednom spoljnom ekranu"</item>
+    <item msgid="5280431949814340475">"Prikaži uređaj na poslednjem ekranu u fokusu"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index d36a864..fc55fff 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktivno (samo levo)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktivno (samo desno)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktivno (levo i desno)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktivno (samo za medije). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktivno (samo za medije). Levo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, desno: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Povezano (podržava deljenje zvuka), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Razmera animacije prelaza"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatorova razmera trajanja"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simuliraj sekundarne ekrane"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Položaj senke na ekranu"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplikacije"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ne čuvaj aktivnosti"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Uništava svaku aktivnost čim je korisnik napusti"</string>
diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml
index e70d694..3339361 100644
--- a/packages/SettingsLib/res/values-be/arrays.xml
+++ b/packages/SettingsLib/res/values-be/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Толькі дысплэй прылады (стандартна)"</item>
+    <item msgid="9161645858025071955">"Знешні дысплэй"</item>
+    <item msgid="114384731934682483">"У залежнасці ад выкарыстання"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Паказваць шчыток толькі на дысплэі прылады"</item>
+    <item msgid="7795034287069726554">"Паказваць прыладу на адным знешнім дысплэі"</item>
+    <item msgid="5280431949814340475">"Паказваць прыладу на дысплэі, які выкарыстоўваўся апошнім"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 29f5542..be86aca 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Выкарыстоўваецца (толькі левы навушнік)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Выкарыстоўваецца (толькі правы навушнік)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Выкарыстоўваецца (левы і правы навушнікі)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Выкарыстоўваецца (толькі для мультымедыя). Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Выкарыстоўваецца (толькі для мультымедыя). Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (левы навушнік), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (правы навушнік)."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Падключана (падтрымліваецца абагульванне аўдыя). Зарад акумулятара: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Маштаб перадачы анімацыі"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Працягласць анімацыі"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Мадэляванне другасных экранаў"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Месца паказу шчытка"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Праграмы"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Не захоўваць дзеянні"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Выдаляць усе дзеянні пасля выхаду карыстальніка"</string>
diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml
index ce497f3..c3bc26f 100644
--- a/packages/SettingsLib/res/values-bg/arrays.xml
+++ b/packages/SettingsLib/res/values-bg/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Само на екрана на устройството (по подразбиране)"</item>
+    <item msgid="9161645858025071955">"Външен екран"</item>
+    <item msgid="114384731934682483">"Въз основа на фокуса"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Показване на падащия панел само на екрана на устройството"</item>
+    <item msgid="7795034287069726554">"Показване на устройството на един външен екран"</item>
+    <item msgid="5280431949814340475">"Показване на устройството на екрана, върху който последно е бил поставен фокусът"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 8d261a2..624c55b 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Активно (само лявото)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Активно (само дясното)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Активно (лявото и дясното)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Активно (само за мултимедия). Батерия – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Активно (само за мултимедия). Л: батерия – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Д: батерия – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Свързано (поддържа споделяне на звука). Батерия – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Скала на преходната анимация"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Скала за Animator"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Симулиране на алтерн. дисплеи"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Позиция на показване на падащия панел"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Приложения"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Без съхран. на дейностите"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Унищож. на всяка дейност при напускане от потребител"</string>
diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml
index f30ff08..2b939d0 100644
--- a/packages/SettingsLib/res/values-bn/arrays.xml
+++ b/packages/SettingsLib/res/values-bn/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"শুধুমাত্র ডিভাইসের ডিসপ্লে (ডিফল্ট)"</item>
+    <item msgid="9161645858025071955">"এক্সটার্নাল ডিসপ্লে"</item>
+    <item msgid="114384731934682483">"ফোকাস অনুযায়ী"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"শুধুমাত্র ডিভাইসের ডিসপ্লেতে শেড দেখুন"</item>
+    <item msgid="7795034287069726554">"শেড একটি এক্সটার্নাল ডিসপ্লেতে দেখুন"</item>
+    <item msgid="5280431949814340475">"ফোকাস করা শেষ ডিসপ্লেতে ডিভাইস দেখুন"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 0ad50cc..fcc99ca 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"চালু আছে (শুধু বাঁদিক)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"চালু আছে (শুধু ডানদিক)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"চালু আছে (বাঁদিক ও ডানদিক)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"চালু আছে (শুধুমাত্র মিডিয়া)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ব্যাটারি।"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"চালু আছে (শুধুমাত্র মিডিয়া), বাঁদিক: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ডানদিক: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ব্যাটারি।"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"কানেক্ট করা আছে (অডিও শেয়ারিংয়ে কাজ করে), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ব্যাটারি।"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ট্র্যানজিশন অ্যানিমেশন স্কেল"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"অ্যানিমেটর সময়কাল স্কেল"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"গৌণ প্রদর্শনগুলি নকল করুন"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"শেড ডিসপ্লে করার পজিশন"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"অ্যাপ"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"অ্যাক্টিভিটি রাখবেন না"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ব্যবহারকারী এটি ছেড়ে যাওয়ার পরে যত তাড়াতাড়ি সম্ভব প্রতিটি অ্যাক্টিভিটি ধ্বংস করুন"</string>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index 069dc04..625112c 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Samo zaslon uređaja (zadano)"</item>
+    <item msgid="9161645858025071955">"Vanjski ekran"</item>
+    <item msgid="114384731934682483">"Na osnovu fokusa"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Prikaži sjenu samo na ekranu uređaja"</item>
+    <item msgid="7795034287069726554">"Prikaži uređaj na jednom vanjskom ekranu"</item>
+    <item msgid="5280431949814340475">"Prikaži uređaj na posljednjem fokusiranom ekranu"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index a30bcfa..fea1fa5 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktivno (samo lijevo)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktivno (samo desno)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktivno (lijevo i desno)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktivno (samo za medijski sadržaj). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktivno (samo za medijski sadržaj). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> baterije, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Povezano (podržava dijeljenje zvuka). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animacije prijelaza"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala trajanja animatora"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulacija sekundarnih ekrana"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Položaj prikaza sjene"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplikacije"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ne čuvaj aktivnosti"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Obustavlja se svaka aktivnost čim je korisnik napusti"</string>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index 133ad13..e9b437e 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Només a la pantalla del dispositiu (opció predeterminada)"</item>
+    <item msgid="9161645858025071955">"Pantalla externa"</item>
+    <item msgid="114384731934682483">"Basat en l\'enfocament"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Mostra l\'ombra només a la pantalla del dispositiu"</item>
+    <item msgid="7795034287069726554">"Mostra el dispositiu en una sola pantalla externa"</item>
+    <item msgid="5280431949814340475">"Mostra el dispositiu a la darrera pantalla en què s\'hagi posat el focus"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index ba733de..3f73bcc 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Actiu (només l\'esquerre)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Actiu (només el dret)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Actiu (esquerre i dret)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Actiu (només contingut multimèdia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Actiu (només contingut multimèdia), E: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connectat (admet compartició d\'àudio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala d\'animació de la transició"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de durada de l\'animació"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simula pantalles secundàries"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Posició de l\'ombra a la pantalla"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplicacions"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"No desis les activitats"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Destrueix activitats quan l\'usuari deixi d\'utilitzar-les"</string>
diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml
index 20405ed6..4bfdaf4 100644
--- a/packages/SettingsLib/res/values-cs/arrays.xml
+++ b/packages/SettingsLib/res/values-cs/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Pouze zobrazení zařízení (výchozí)"</item>
+    <item msgid="9161645858025071955">"Externí displej"</item>
+    <item msgid="114384731934682483">"Výběr"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Zobrazovat panel pouze na displeji zařízení"</item>
+    <item msgid="7795034287069726554">"Zobrazovat panel na jednom externím displeji"</item>
+    <item msgid="5280431949814340475">"Zobrazovat panel na naposledy vybraném displeji"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 1a239a1..940e2f6 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktivní (pouze levé)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktivní (pouze pravé)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktivní (levé a pravé)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktivní (pouze média). Baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktivní (pouze média), baterie: L <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, P <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Připojeno (podporuje sdílení zvuku), baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Měřítko animace přeměny"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Měřítko délky animace"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulovat sekundární obrazovky"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Pozice panelu"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplikace"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Neukládat aktivity"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Rušit všechny činnosti, jakmile je uživatel zavře"</string>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index 3d2d6c7..6949755 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Kun på enhedens skærm (standard)"</item>
+    <item msgid="9161645858025071955">"Ekstern skærm"</item>
+    <item msgid="114384731934682483">"Fokusbaseret"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Vis kun skygge på enhedens skærm"</item>
+    <item msgid="7795034287069726554">"Vis enheden på en enkelt ekstern skærm"</item>
+    <item msgid="5280431949814340475">"Vis enheden på den skærm, der sidst var i fokus"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 3753e033..2b30847 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktiveret (kun venstre)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktiveret (kun højre)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktiveret (venstre og højre)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiveret (kun for medier). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiveret (kun for medier), V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Forbundet (understøtter lyddeling). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Overgangsanimationsskala"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatorvarighedsskala"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simuler sekundære skærme"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Placering af skærmens skygge"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Behold ikke aktiviteter"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Luk hver aktivitet, så snart brugeren forlader den"</string>
diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml
index 291f4e5..adddd77 100644
--- a/packages/SettingsLib/res/values-de/arrays.xml
+++ b/packages/SettingsLib/res/values-de/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Nur Gerätedisplay (Standard)"</item>
+    <item msgid="9161645858025071955">"Externes Display"</item>
+    <item msgid="114384731934682483">"Fokusbasiert"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Leiste nur auf dem Display des Geräts anzeigen"</item>
+    <item msgid="7795034287069726554">"Gerät auf einem einzigen externen Display anzeigen"</item>
+    <item msgid="5280431949814340475">"Gerät auf zuletzt fokussiertem Display anzeigen"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 7d0b848..e9e9275f 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktiv (nur links)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktiv (nur rechts)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktiv (links und rechts)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiv (nur Medien). Akku: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiv (nur Medien). Akku links: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Akku rechts: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Verbunden (unterstützt Audiofreigabe). Akku: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Übergangsanimationsfaktor"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animationsdauerfaktor"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Sekundäre Displays simulieren"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Position der Leiste auf dem Display"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Aktivitäten nicht speichern"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Aktivität löschen, sobald der Nutzer diese beendet"</string>
diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml
index 27927eb..9d7612c 100644
--- a/packages/SettingsLib/res/values-el/arrays.xml
+++ b/packages/SettingsLib/res/values-el/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Μόνο οθόνη συσκευής (Προεπιλογή)"</item>
+    <item msgid="9161645858025071955">"Εξωτερική οθόνη"</item>
+    <item msgid="114384731934682483">"Με εστίαση"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Εμφάνιση σκίασης μόνο στην οθόνη συσκευής"</item>
+    <item msgid="7795034287069726554">"Εμφάνιση συσκευής σε μία εξωτερική οθόνη"</item>
+    <item msgid="5280431949814340475">"Εμφάνιση συσκευής στην τελευταία οθόνη με εστίαση"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 915cabb..4662c3c 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Ενεργό (μόνο το αριστερό)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Ενεργό (μόνο το δεξί)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Ενεργό (αριστερό και δεξί)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Ενεργό (μόνο για μέσα). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> μπαταρία."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Ενεργό (μόνο για μέσα). Α: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Δ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> μπαταρία."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Συνδεδεμένο (υποστηρίζει κοινή χρήση ήχου). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> μπαταρία."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Κλίμακα κίνησης μετάβασης"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Κλίμ. διάρ. Animator"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Προσομ. δευτερ. προβολών"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Θέση οθόνης σκίασης"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Εφαρμογές"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Μη διατήρ. δραστηριοτήτων"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Διαγραφή κάθε δραστηριότητας μετά τον τερματισμό"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml
index 7e846fb..8c27ec6 100644
--- a/packages/SettingsLib/res/values-en-rAU/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Device display only (default)"</item>
+    <item msgid="9161645858025071955">"External display"</item>
+    <item msgid="114384731934682483">"Focus-based"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Show shade on device display only"</item>
+    <item msgid="7795034287069726554">"Show device on single external display"</item>
+    <item msgid="5280431949814340475">"Show device on last focused display"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index d9c35f5..b281f4c 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Active (left only)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Active (right only)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Active (left and right)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Active (media only). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Active (media only). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connected (supports audio sharing). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulate secondary displays"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Shade display position"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Don\'t keep activities"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Destroy every activity as soon as the user leaves it"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/arrays.xml b/packages/SettingsLib/res/values-en-rCA/arrays.xml
index ec6894a..cfe77ca 100644
--- a/packages/SettingsLib/res/values-en-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rCA/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Device display only (Default)"</item>
+    <item msgid="9161645858025071955">"External display"</item>
+    <item msgid="114384731934682483">"Focus-based"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Show shade on device display only"</item>
+    <item msgid="7795034287069726554">"Show device on single external display"</item>
+    <item msgid="5280431949814340475">"Show device on last focused display"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 887841c..3d5d5c7 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -110,6 +110,7 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Active (left only)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Active (right only)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Active (left and right)"</string>
+    <string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Couldn’t update surroundings"</string>
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Active (media only). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Active (media only). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connected (supports audio sharing). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
@@ -423,6 +424,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulate secondary displays"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Shade display position"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Don’t keep activities"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Destroy every activity as soon as the user leaves it"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/arrays.xml b/packages/SettingsLib/res/values-en-rGB/arrays.xml
index 7e846fb..8c27ec6 100644
--- a/packages/SettingsLib/res/values-en-rGB/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rGB/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Device display only (default)"</item>
+    <item msgid="9161645858025071955">"External display"</item>
+    <item msgid="114384731934682483">"Focus-based"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Show shade on device display only"</item>
+    <item msgid="7795034287069726554">"Show device on single external display"</item>
+    <item msgid="5280431949814340475">"Show device on last focused display"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index d9c35f5..b281f4c 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Active (left only)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Active (right only)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Active (left and right)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Active (media only). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Active (media only). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connected (supports audio sharing). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulate secondary displays"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Shade display position"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Don\'t keep activities"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Destroy every activity as soon as the user leaves it"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml
index 7e846fb..8c27ec6 100644
--- a/packages/SettingsLib/res/values-en-rIN/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Device display only (default)"</item>
+    <item msgid="9161645858025071955">"External display"</item>
+    <item msgid="114384731934682483">"Focus-based"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Show shade on device display only"</item>
+    <item msgid="7795034287069726554">"Show device on single external display"</item>
+    <item msgid="5280431949814340475">"Show device on last focused display"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index d9c35f5..b281f4c 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Active (left only)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Active (right only)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Active (left and right)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Active (media only). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Active (media only). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connected (supports audio sharing). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulate secondary displays"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Shade display position"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Don\'t keep activities"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Destroy every activity as soon as the user leaves it"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml
index 541f4db..daf9ab9 100644
--- a/packages/SettingsLib/res/values-es-rUS/arrays.xml
+++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Solo en la pantalla del dispositivo (predeterminado)"</item>
+    <item msgid="9161645858025071955">"Pantalla externa"</item>
+    <item msgid="114384731934682483">"Basado en el enfoque"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Mostrar sobra solo en la pantalla del dispositivo"</item>
+    <item msgid="7795034287069726554">"Mostrar dispositivo en una sola pantalla externa"</item>
+    <item msgid="5280431949814340475">"Mostrar dispositivo en la última pantalla enfocada"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 191a8eb..6ad6008 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Activo (solo izquierdo)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Activo (solo derecho)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Activos (izquierdo y derecho)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Activado (solo para contenido multimedia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Activo (solo para contenido multimedia); I: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>; D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batería."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (admite el uso compartido de audio); <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animación de transición"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duración de animador"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simular pantallas secundarias"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Posición de visualización de la sombra"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplicaciones"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Eliminar actividades"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Descartar todas las actividades en cuanto el usuario las abandona"</string>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index b99219c..a4bb49e 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Solo en la pantalla del dispositivo (predeterminado)"</item>
+    <item msgid="9161645858025071955">"Pantalla externa"</item>
+    <item msgid="114384731934682483">"Basado en el enfoque"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Mostrar el panel solo en la pantalla del dispositivo"</item>
+    <item msgid="7795034287069726554">"Mostrar el dispositivo en una sola pantalla externa"</item>
+    <item msgid="5280431949814340475">"Mostrar el dispositivo en la última pantalla enfocada"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 95ebbfa..6019751 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Activo (solo izquierdo)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Activo (solo derecho)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Activo (izquierdo y derecho)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Activo (solo multimedia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Activo (solo multimedia). Izquierdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de batería. Derecho: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batería."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (permite compartir audio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animación de transición"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duración de animación"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simular pantallas secundarias"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Posición del panel en la pantalla"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplicaciones"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"No mantener actividades"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Destruir actividades cuando el usuario salga de ellas"</string>
diff --git a/packages/SettingsLib/res/values-et/arrays.xml b/packages/SettingsLib/res/values-et/arrays.xml
index 6762abf..9a77991 100644
--- a/packages/SettingsLib/res/values-et/arrays.xml
+++ b/packages/SettingsLib/res/values-et/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Ainult seadme ekraan (vaikimisi)"</item>
+    <item msgid="9161645858025071955">"Väline ekraan"</item>
+    <item msgid="114384731934682483">"Fookusepõhine"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Kuva menüü ainult seadme ekraanil"</item>
+    <item msgid="7795034287069726554">"Kuva seade ühe välisel ekraanil"</item>
+    <item msgid="5280431949814340475">"Kuva seade viimati esile tõstetud ekraanil"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 802c1e2..773b1e6 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktiivne (ainult vasak)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktiivne (ainult parem)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktiivne (vasak ja parem)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiivne (ainult meedia). Aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiivne (ainult meedia). Aku: V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, P: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Ühendatud (toetab heli jagamist). Aku <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Ülemineku animatsioonimastaap"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animaatori kestuse mastaap"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Modelleeri teisi ekraane"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Menüü kuvamise asukoht"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Rakendused"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ära hoia tegevusi alles"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Hävita kõik tegevused kohe, kui kasutaja neist lahkub"</string>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index 6ed484c..3d59a27 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -153,15 +153,15 @@
     <item msgid="1333279807604675720">"Estereoa"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_titles">
-    <item msgid="1241278021345116816">"Audioaren kalitatea areagotzeko optimizatua (990 Kb/s / 909 Kb/s)"</item>
+    <item msgid="1241278021345116816">"Audioaren kalitatea hobetzeko optimizatua (990 Kb/s / 909 Kb/s)"</item>
     <item msgid="3523665555859696539">"Audioaren eta konexioaren kalitate orekatua (660 Kb/s / 606 Kb/s)"</item>
-    <item msgid="886408010459747589">"Konexioaren kalitatea areagotzeko optimizatua (330 Kb/s / 303 Kb/s)"</item>
+    <item msgid="886408010459747589">"Konexioaren kalitatea hobetzeko optimizatua (330 Kb/s / 303 Kb/s)"</item>
     <item msgid="3808414041654351577">"Emaitzarik onenak (bit-abiadura egokitua)"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
-    <item msgid="804499336721569838">"Audioaren kalitatea areagotzeko optimizatua"</item>
+    <item msgid="804499336721569838">"Audioaren kalitatea hobetzeko optimizatua"</item>
     <item msgid="7451422070435297462">"Orekatu audioaren eta konexioaren kalitateak"</item>
-    <item msgid="6173114545795428901">"Konexioaren kalitatea areagotzeko optimizatua"</item>
+    <item msgid="6173114545795428901">"Konexioaren kalitatea hobetzeko optimizatua"</item>
     <item msgid="4349908264188040530">"Emaitzarik onenak (bit-abiadura egokitua)"</item>
   </string-array>
   <string-array name="bluetooth_audio_active_device_summaries">
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Gailuaren pantailan soilik (lehenetsia)"</item>
+    <item msgid="9161645858025071955">"Kanpoko pantailan"</item>
+    <item msgid="114384731934682483">"Fokuaren arabera"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Erakutsi itzalak gailuaren pantailan soilik"</item>
+    <item msgid="7795034287069726554">"Erakutsi gailua kanpoko pantaila bakarrean"</item>
+    <item msgid="5280431949814340475">"Erakutsi gailua fokuratutako azken pantailan"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 16dd1f6..274b9a1 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktibo (ezkerrekoa soilik)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktibo (eskuinekoa soilik)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktibo (ezkerrekoa eta eskuinekoa)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktibo (multimedia-edukia soilik). Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktibo (multimedia-edukia soilik). L aldearen bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>. R aldearen bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Konektatuta (audioa partekatzeko eginbidea onartzen du). Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Trantsizioen animazio-eskala"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatzailearen iraupen-eskala"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulatu bigarren mailako pantailak"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Itzalak pantailan duen posizioa"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplikazioak"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ez mantendu jarduerak"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Ezabatu jarduerak erabiltzailea haietatik irtetean"</string>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index d150538..9e1da41 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"۲"</item>
     <item msgid="4779928470672877922">"۳"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"فقط نمایشگر دستگاه (پیش‌فرض)"</item>
+    <item msgid="9161645858025071955">"نمایشگر خارجی"</item>
+    <item msgid="114384731934682483">"کانونی‌محور"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"نمایش سایه فقط در نمایشگر دستگاه"</item>
+    <item msgid="7795034287069726554">"نمایش دستگاه در یک نمایشگر خارجی"</item>
+    <item msgid="5280431949814340475">"نمایش دستگاه در آخرین نمایشگر کانونی‌شده"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"نمایشگر_پیش‌فرض"</item>
+    <item msgid="774789415968826925">"هر_نمایشگر_خارجی"</item>
+    <item msgid="7880769915418638436">"آخرین_لمس_نوار_وضعیت"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 85ef0f9..6154b8c 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"فعال (فقط چپ)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"فعال (فقط راست)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"فعال (چپ و راست)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"فعال (فقط رسانه). باتری: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"فعال (فقط رسانه). باتری چپ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>، باتری راست: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"متصل (از اشتراک صدا پشتیبانی می‌کند)، باتری: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"مقیاس پویانمایی انتقالی"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"مقیاس طول مدت مقیاس مدت پویانماساز"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"شبیه‌سازی نمایشگر ثانویه"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"موقعیت سایه نمایشگر"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"برنامه‌ها"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"فعالیت‌ها نگه داشته نشوند"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"از بین بردن هر فعالیت به محض خروج کاربر از آن"</string>
diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml
index 92814de..0c970ec 100644
--- a/packages/SettingsLib/res/values-fi/arrays.xml
+++ b/packages/SettingsLib/res/values-fi/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Vain laitteen näyttö (oletus)"</item>
+    <item msgid="9161645858025071955">"Ulkoinen näyttö"</item>
+    <item msgid="114384731934682483">"Kohdistusperustainen"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Näytä ilmoitusalue vain laitteen näytöllä"</item>
+    <item msgid="7795034287069726554">"Näytä laite yhdellä ulkoisella näytöllä"</item>
+    <item msgid="5280431949814340475">"Näytä laite viimeksi kohdistetulla näytöllä"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 4b18d2f..7baf2a0 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktiivinen (vain vasen)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktiivinen (vain oikea)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktiivinen (vasen ja oikea)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiivinen (vain media). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> virtaa."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiivinen (vain media). V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, O: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> virtaa."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Yhdistetty (tukee audionjakoa). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> virtaa."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Siirtymä"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animaattori"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simuloi toissijaiset näytöt"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Ilmoitusalueen sijainti näytöllä"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Sovellukset"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Älä säilytä toimintoja"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Tuhoa kaikki toiminnot, kun käyttäjä poistuu"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
index 15cb17d..6fc0ed9 100644
--- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Écran de l\'appareil seulement (par défaut)"</item>
+    <item msgid="9161645858025071955">"Écran externe"</item>
+    <item msgid="114384731934682483">"Affichage mis en évidence"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Afficher le volet sur l\'écran de l\'appareil seulement"</item>
+    <item msgid="7795034287069726554">"Afficher l\'appareil sur un seul écran externe"</item>
+    <item msgid="5280431949814340475">"Afficher l\'appareil sur le dernier affichage mis en évidence"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index a1d1599..699fa7f 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Actif (gauche seulement)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Actif (droite seulement)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Actif (gauche et droite)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Actif (contenu multimédia uniquement). Pile à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Actif (contenu multimédia uniquement). G. : pile à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, D. : pile à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connecté (prise en charge du partage audio). Pile à <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Éch. d\'animation des transitions"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Échelle durée animation"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simuler affich. secondaires"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Position d\'affichage du volet"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Applis"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ne pas conserver activités"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Supprimer immédiatement les activités abandonnées"</string>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index b32adc9..970e217 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Écran de l\'appareil uniquement (par défaut)"</item>
+    <item msgid="9161645858025071955">"Écran externe"</item>
+    <item msgid="114384731934682483">"Basé sur la sélection"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Afficher le volet sur l\'écran de l\'appareil uniquement"</item>
+    <item msgid="7795034287069726554">"Afficher l\'appareil sur un seul écran externe"</item>
+    <item msgid="5280431949814340475">"Afficher l\'appareil sur le dernier écran sélectionné"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index f22f8bf..73dbdbf 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Actif (gauche uniquement)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Actif (droit uniquement)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Actifs (gauche et droit)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Actif (multimédia uniquement). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batterie."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Actif (multimédia uniquement). Gauche : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de batterie, droit : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batterie."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connecté (compatible avec le partage audio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batterie."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Échelle d\'animation des transitions"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Échelle de durée d\'animation"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simuler des écrans secondaires"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Position d\'affichage du volet"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Applications"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ne pas conserver les activités"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Supprimer immédiatement les activités abandonnées"</string>
diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml
index 8f7a8b6..cd085fa 100644
--- a/packages/SettingsLib/res/values-gl/arrays.xml
+++ b/packages/SettingsLib/res/values-gl/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Só pantalla do dispositivo (opción predeterminada)"</item>
+    <item msgid="9161645858025071955">"Pantalla externa"</item>
+    <item msgid="114384731934682483">"En función do enfoque"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Mostrar panel despregable só na pantalla do dispositivo"</item>
+    <item msgid="7795034287069726554">"Mostrar dispositivo nunha única pantalla externa"</item>
+    <item msgid="5280431949814340475">"Mostrar dispositivo na última pantalla enfocada"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"pantalla_predeterminada"</item>
+    <item msgid="774789415968826925">"calquera_pantalla_externa"</item>
+    <item msgid="7880769915418638436">"último_toque_barra_estado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 6a22a9b..9f14f7c 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Activo (só o esquerdo)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Activo (só o dereito)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Activos (o esquerdo e o dereito)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Activo (só contido multimedia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Activo (só contido multimedia). Esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de batería. Dereito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de batería."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (compatible con audio compartido). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de batería."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala animación-transición"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala duración animador"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simular pantallas secundarias"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Posición do panel despregable na pantalla"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplicacións"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Non manter actividades"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Destrúe as actividades cando o usuario non as usa"</string>
diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml
index 4f7cbd2..912df2d 100644
--- a/packages/SettingsLib/res/values-gu/arrays.xml
+++ b/packages/SettingsLib/res/values-gu/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"માત્ર ડિવાઇસનું ડિસ્પ્લે (ડિફૉલ્ટ)"</item>
+    <item msgid="9161645858025071955">"બાહ્ય ડિસ્પ્લે"</item>
+    <item msgid="114384731934682483">"ફોકસ-આધારિત"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"માત્ર ડિવાઇસના ડિસ્પ્લે પર શેડ બતાવો"</item>
+    <item msgid="7795034287069726554">"માત્ર એક બાહ્ય ડિસ્પ્લે પર ડિવાઇસ બતાવો"</item>
+    <item msgid="5280431949814340475">"છેલ્લે ફોકસ કરેલા ડિસ્પ્લે પર ડિવાઇસ બતાવો"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 91518d3..74b19f6 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"ચાલુ છે (માત્ર ડાબી બાજુ)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"ચાલુ છે (માત્ર જમણી બાજુ)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"ચાલુ છે (ડાબી અને જમણી બાજુ)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"સક્રિય (માત્ર મીડિયા માટે). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"સક્રિય (માત્ર મીડિયા માટે). ડાબી બાજુ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, જમણી બાજુ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> બૅટરી."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"કનેક્ટેડ (ઑડિયો શેરિંગને સપોર્ટ કરે છે). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> બૅટરી."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ટ્રાન્ઝિશન ઍનિમેશન સ્કેલ"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ઍનિમેટર અવધિ સ્કેલ"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"સેકન્ડરી ડિસ્પ્લેનું અનુકરણ કરો"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"શેડના ડિસ્પ્લેની સ્થિતિ"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"ઍપ"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"પ્રવૃત્તિઓ રાખશો નહીં"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"જેવો વપરાશકર્તા તેને છોડે, તરત જ દરેક પ્રવૃત્તિ નષ્ટ કરો"</string>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index 2173ad6..25d6388 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"सिर्फ़ डिवाइस का डिसप्ले (डिफ़ॉल्ट)"</item>
+    <item msgid="9161645858025071955">"बाहरी डिसप्ले पर"</item>
+    <item msgid="114384731934682483">"फ़ोकस के हिसाब से"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"सिर्फ़ डिवाइस के डिसप्ले पर शेड दिखाएं"</item>
+    <item msgid="7795034287069726554">"शेड को बाहरी डिसप्ले पर दिखाएं"</item>
+    <item msgid="5280431949814340475">"फ़ोकस किए गए पिछले डिसप्ले पर शेड दिखाएं"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 10a46225..8f9229a 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"सिर्फ़ बाईं तरफ़ वाला चालू है"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"सिर्फ़ दाईं तरफ़ वाला चालू है"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"बाईं और दाईं तरफ़ वाला चालू है"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"चालू है (सिर्फ़ मीडिया के लिए). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"चालू है (सिर्फ़ मीडिया के लिए). बायां हेडसेट: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, दायां हेडसेट: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बैटरी."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"कनेक्ट हो गया (ऑडियो शेयर करने की सुविधा काम करती है). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बैटरी."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ट्रांज़िशन ऐनिमेशन स्‍केल"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ऐनिमेटर ड्यूरेशन स्केल"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"कई साइज़ के डिसप्ले बनाएं"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"शेड दिखने की स्थिति"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"ऐप्लिकेशन"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"गतिविधियों को न रखें"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"उपयोगकर्ता के छोड़ते ही हर गतिविधि को खत्म करें"</string>
diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml
index f4bb419..639e39e 100644
--- a/packages/SettingsLib/res/values-hr/arrays.xml
+++ b/packages/SettingsLib/res/values-hr/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Samo zaslon uređaja (zadano)"</item>
+    <item msgid="9161645858025071955">"Vanjski zaslon"</item>
+    <item msgid="114384731934682483">"Na temelju fokusa"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Prikaži sjenu samo na zaslonu uređaja"</item>
+    <item msgid="7795034287069726554">"Prikaži uređaj na jednom vanjskom zaslonu"</item>
+    <item msgid="5280431949814340475">"Prikaži uređaj na posljednjem fokusiranom zaslonu"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index c3284ae..3a18da0 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktivno (samo lijevo)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktivno (samo desno)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktivno (lijevo i desno)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktivno (samo medijski sadržaji). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktivno (samo medijski sadržaji), L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterije."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Povezano (podržava zajedničko slušanje). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterije."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Brzina animacije prijelaza"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Brzina generiranja animacija"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulacija sekundarnih zaslona"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Položaj prikaza sjene"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplikacije"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ukloni aktivnosti"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Aktivnost se uklanja čim je korisnik napusti"</string>
diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml
index 6ece81a..d131966 100644
--- a/packages/SettingsLib/res/values-hu/arrays.xml
+++ b/packages/SettingsLib/res/values-hu/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Csak az eszköz kijelzője (alapértelmezett)"</item>
+    <item msgid="9161645858025071955">"Külső kijelző"</item>
+    <item msgid="114384731934682483">"Fókusz alapján"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Felület megjelenítése csak az eszköz kijelzőjén"</item>
+    <item msgid="7795034287069726554">"Felület megjelenítése egyetlen külső kijelzőn"</item>
+    <item msgid="5280431949814340475">"Felület megjelenítése a legutóbb fókuszban lévő kijelzőn"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index dcf1610..00ca5c6 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktív (csak bal)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktív (csak jobb)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktív (bal és jobb)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktív (csak médiatartalom lejátszása esetén). Akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktív (csak médiatartalom lejátszása esetén). Akkumulátorok töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (bal) és <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (jobb)."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Csatlakoztatva (támogatja a hang megosztását). Akkumulátor töltöttségi szintje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Áttűnési animáció tempója"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animáció tempója"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Másodlagos kijelzők szimulálása"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Felület megjelenítési pozíciója"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Alkalmazások"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Tevékenységek törlése"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Tevékenységek törlése, amint elhagyják azokat"</string>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index 6819f31..5654501 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Միայն սարքի էկրանը (կանխադրված)"</item>
+    <item msgid="9161645858025071955">"Արտաքին էկրան"</item>
+    <item msgid="114384731934682483">"Ֆոկուսի հիման վրա"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Ցույց տալ երանգը միայն սարքի էկրանին"</item>
+    <item msgid="7795034287069726554">"Ցույց տալ սարքը մեկ արտաքին էկրանին"</item>
+    <item msgid="5280431949814340475">"Ցույց տալ սարքը վերջին ֆոկուսավորված էկրանին"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index cd6cfdf..58eca5c 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Ակտիվ է (միայն ձախ)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Ակտիվ է (միայն աջ)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Ակտիվ է (ձախ և աջ)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Ակտիվ է (միայն մեդիա)։ Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>։"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Ակտիվ է (միայն մեդիա)։ Ձախ ականջակալի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, աջ ականջակալի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>։"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Միացված է (աջակցում է աուդիոյի փոխանցում)։ Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>։"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Անցումների շարժապատկեր"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Շարժանկարի տևողության սանդղակ"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Կրկնաստեղծել երկրորդական էկրան"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Երանգի ցուցադրման դիրքը"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Հավելվածներ"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Չպահել գործողությունները"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Օգտատիրոջ դուրս գալուց հետո հեռացնել բոլոր գործողությունները"</string>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 00ea04d..c256e8c 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Hanya layar perangkat (Default)"</item>
+    <item msgid="9161645858025071955">"Layar eksternal"</item>
+    <item msgid="114384731934682483">"Berbasis fokus"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Tampilkan shade hanya di layar perangkat"</item>
+    <item msgid="7795034287069726554">"Tampilkan perangkat di satu layar eksternal"</item>
+    <item msgid="5280431949814340475">"Tampilkan perangkat di layar yang terakhir difokuskan"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index cd53507..1652ebf 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktif (hanya kiri)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktif (hanya kanan)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktif (kiri dan kanan)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktif (hanya media). Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktif (hanya media). Baterai L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Terhubung (mendukung berbagi audio). Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animasi transisi"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala durasi animator"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulasikan tampilan sekunder"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Posisi shade layar"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplikasi"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Jangan simpan aktivitas"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Hancurkan aktivitas setelah ditinggal pengguna"</string>
diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml
index 928cdfa..1d81344 100644
--- a/packages/SettingsLib/res/values-is/arrays.xml
+++ b/packages/SettingsLib/res/values-is/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Aðeins skjár tækis (sjálfgefið)"</item>
+    <item msgid="9161645858025071955">"Ytri skjár"</item>
+    <item msgid="114384731934682483">"Byggt á fókus"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Aðeins skyggja skjá tækis"</item>
+    <item msgid="7795034287069726554">"Sýna tæki á einum ytri skjá"</item>
+    <item msgid="5280431949814340475">"Sýna tæki á skjá sem var síðast í fókus"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index ff4e38b..bc766325 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Kveikt (eingöngu vinstra)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Kveikt (eingöngu hægra)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Kveikt (vinstra og hægra)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Virkt (eingöngu margmiðlunarefni). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlöðuhleðsla."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Virkt (eingöngu margmiðlunarefni), V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> rafhlöðuhleðsla."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Tengt (styður hljóðdeilingu), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> rafhlöðuhleðsla."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Lengd hreyfiumbreytinga"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Tímalengd hreyfiáhrifa"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Herma eftir aukaskjáum"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Staðsetning skugga á skjá"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Forrit"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ekki vista virkni"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Eyðileggja öll verk um leið og notandi yfirgefur þau"</string>
diff --git a/packages/SettingsLib/res/values-it/arrays.xml b/packages/SettingsLib/res/values-it/arrays.xml
index c9f31ff..331410c 100644
--- a/packages/SettingsLib/res/values-it/arrays.xml
+++ b/packages/SettingsLib/res/values-it/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Solo display del dispositivo (impostazione predefinita)"</item>
+    <item msgid="9161645858025071955">"Display esterno"</item>
+    <item msgid="114384731934682483">"In base alla selezione"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Mostra l\'area delle notifiche solo sul display del dispositivo"</item>
+    <item msgid="7795034287069726554">"Mostra il dispositivo su un singolo display esterno"</item>
+    <item msgid="5280431949814340475">"Mostra il dispositivo sull\'ultimo display selezionato"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 183a799..a604e5b 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -110,6 +110,7 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Attivo (solo sinistro)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Attivo (solo destro)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Attivi (destro e sinistro)"</string>
+    <string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Impossibile aggiornare audio ambientale"</string>
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Attivo (solo contenuti multimediali). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> di batteria."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Attivo (solo contenuti multimediali). S: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> di batteria. D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> di batteria."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Connesso (supporta la condivisione audio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> di batteria."</string>
@@ -423,6 +424,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Scala animazione transizione"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Scala durata animatore"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simula display secondari"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Posizione display area delle notifiche"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"App"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Non conservare attività"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Elimina ogni attività appena l\'utente la interrompe"</string>
diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml
index 01bb1fb..d1771fc 100644
--- a/packages/SettingsLib/res/values-iw/arrays.xml
+++ b/packages/SettingsLib/res/values-iw/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"מסך המכשיר בלבד (ברירת המחדל)"</item>
+    <item msgid="9161645858025071955">"מסך חיצוני"</item>
+    <item msgid="114384731934682483">"לפי התמקדות"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"הצגת הצללה במסך המכשיר בלבד"</item>
+    <item msgid="7795034287069726554">"הצגת המכשיר במסך חיצוני אחד"</item>
+    <item msgid="5280431949814340475">"הצגת המכשיר במסך האחרון שהתמקדת בו"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index c2b9cbc..f51c916 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"פעיל (שמאל בלבד)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"פעיל (ימין בלבד)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"פעיל (ימין ושמאל)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"פעיל (מדיה בלבד). סוללה: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"פעיל (מדיה בלבד). סוללה בצד שמאל: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, סוללה בצד ימין: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"מחובר (תמיכה בשיתוף אודיו). סוללה: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"קנה מידה לאנימציית מעבר"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"קנה מידה למשך זמן אנימציה"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"יצירת הדמיה של תצוגות משניות"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"מיקום התצוגה של ההצללה"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"אפליקציות"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"ללא שמירת פעילויות"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"השמדת כל פעילות ברגע שהמשתמש עוזב אותה"</string>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index 31bcec1..9dc234b 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"デバイスのディスプレイのみ(デフォルト)"</item>
+    <item msgid="9161645858025071955">"外部ディスプレイ"</item>
+    <item msgid="114384731934682483">"フォーカスに基づく"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"デバイスのディスプレイにのみシェードを表示する"</item>
+    <item msgid="7795034287069726554">"1 台の外部ディスプレイにデバイスを表示する"</item>
+    <item msgid="5280431949814340475">"最後にフォーカスされたディスプレイにデバイスを表示する"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 081ab48..923054d 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"アクティブ(左のみ)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"アクティブ(右のみ)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"アクティブ(左と右)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"有効(メディアのみ)。バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"有効(メディアのみ)。左: バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>、右: バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>。"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"接続済み(音声の共有をサポート)。バッテリー残量 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"トランジション アニメ スケール"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 再生時間スケール"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"第2画面のシミュレーション"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"シェードの表示位置"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"アプリ"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"アクティビティを保持しない"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ユーザーが離れたアクティビティを直ちに破棄する"</string>
diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml
index 4de27e7..8d1adf6 100644
--- a/packages/SettingsLib/res/values-ka/arrays.xml
+++ b/packages/SettingsLib/res/values-ka/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"მხოლოდ მოწყობილობის ეკრანი (ნაგულისხმევი)"</item>
+    <item msgid="9161645858025071955">"გარე ეკრანი"</item>
+    <item msgid="114384731934682483">"ფოკუსის მიხედვით"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"ჩრდილის ჩვენება მხოლოდ მოწყობილობის ეკრანზე"</item>
+    <item msgid="7795034287069726554">"ჩრდილის ჩვენება ერთ გარე ეკრანზე"</item>
+    <item msgid="5280431949814340475">"მოწყობილობის ჩვენება ბოლო ფოკუსირებულ ეკრანზე"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 0ca04a1..e8f1b07 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"აქტიური (მხოლოდ მარცხენა)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"აქტიური (მხოლოდ მარჯვენა)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"აქტიური (მარცხენა და მარჯვენა)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"აქტიური (მხოლოდ მედია). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>%% ბატარეა."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"აქტიური (მხოლოდ მედია), მარცხენა: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, მარჯვენა:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ბატარეა."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"დაკავშირებული (აუდიოს გაზიარება მხარდაჭერილია). ბატარეა <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"გადასვლის მასშტაბი"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ანიმაციების ხანგრძლივობის მასშტაბი"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"მეორადი ეკრანების სიმულაცია"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"ჩრდილის პოზიცია ეკრანზე"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"აპები"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"ნუ შეინარჩუნებ მოქმედებებს"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ნებისმიერი აქტივობის განადგურება დასრულებისთანავე"</string>
diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml
index 6669820..e8996de 100644
--- a/packages/SettingsLib/res/values-kk/arrays.xml
+++ b/packages/SettingsLib/res/values-kk/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Тек құрылғы дисплейі (әдепкі)"</item>
+    <item msgid="9161645858025071955">"Сыртқы дисплей"</item>
+    <item msgid="114384731934682483">"Назарға негізделген"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Құрылғы дисплейінде ғана реңк көрсету"</item>
+    <item msgid="7795034287069726554">"Жалғыз сыртқы дисплейі бар құрылғыны көрсету"</item>
+    <item msgid="5280431949814340475">"Соңғы рет назарда болған дисплейдегі құрылғыны көрсету"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 87917af..a88517d 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Істеп тұр (тек сол жағы)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Істеп тұр (тек оң жағы)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Істеп тұр (екі жағы да)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Істеп тұр (тек мультимедиа). Батарея зарядының деңгейі – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Істеп тұр (тек мультимедиа). Сол жақ: батарея зарядының деңгейі — <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>. Оң жақ: батарея зарядының деңгейі — <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Жалғанып тұр (аудио бөлісу мүмкіндігі бар). Батарея зарядының деңгейі – <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Ауысу анимациясының өлшемі"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Аниматор ұзақтығы"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Қосымша дисплей симуляциясы"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Реңк дисплей позициясы"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Қолданбалар"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Әрекеттерді сақтамау"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Әр әрекетті пайдаланушы аяқтай салысымен жою"</string>
diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml
index 3a533ce..ee6ee56 100644
--- a/packages/SettingsLib/res/values-km/arrays.xml
+++ b/packages/SettingsLib/res/values-km/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"ផ្ទាំងអេក្រង់ឧបករណ៍តែប៉ុណ្ណោះ (លំនាំដើម)"</item>
+    <item msgid="9161645858025071955">"ផ្ទាំង​អេក្រង់​ខាង​ក្រៅ"</item>
+    <item msgid="114384731934682483">"ផ្អែកលើការផ្ដោត"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"បង្ហាញផ្ទាំងនៅលើផ្ទាំងអេក្រង់ឧបករណ៍តែប៉ុណ្ណោះ"</item>
+    <item msgid="7795034287069726554">"បង្ហាញឧបករណ៍នៅលើផ្ទាំងអេក្រង់ខាងក្រៅតែមួយ"</item>
+    <item msgid="5280431949814340475">"បង្ហាញឧបករណ៍នៅលើផ្ទាំងអេក្រង់ដែលផ្ដោតចុងក្រោយ"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 2398ca8..41b427a 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"សកម្ម (ខាងឆ្វេងប៉ុណ្ណោះ)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"សកម្ម (ខាងស្ដាំប៉ុណ្ណោះ)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"សកម្ម (ខាងឆ្វេង និងខាងស្ដាំ)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"សកម្ម (តែមេឌៀប៉ុណ្ណោះ)។ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>។"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"សកម្ម (តែមេឌៀប៉ុណ្ណោះ)។ ឆ្វេង៖ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ស្ដាំ៖ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>។"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"បានភ្ជាប់ (អាចប្រើការស្ដាប់សំឡេងរួមគ្នា)។ ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>។"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"មាត្រដ្ឋាន​ចលនាបែបផែនឆ្លង"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"មាត្រដ្ឋាន​រយៈពេល​ចលនា"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"ត្រាប់ជាអេក្រង់​ទី​ពីរ"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"ទីតាំងបង្ហាញផ្ទាំង"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"កម្មវិធី"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"កុំ​រក្សា​ទុកសកម្មភាព"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"បំផ្លាញ​គ្រប់​សកម្មភាព ពេល​អ្នក​ប្រើ​ចាកចេញ"</string>
diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml
index 1c8112a..51e6e15 100644
--- a/packages/SettingsLib/res/values-kn/arrays.xml
+++ b/packages/SettingsLib/res/values-kn/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"ಸಾಧನದ ಡಿಸ್‌ಪ್ಲೇ ಮಾತ್ರ (ಡೀಫಾಲ್ಟ್)"</item>
+    <item msgid="9161645858025071955">"ಬಾಹ್ಯ ಡಿಸ್‌ಪ್ಲೇ"</item>
+    <item msgid="114384731934682483">"ಫೋಕಸ್-ಆಧಾರಿತ"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"ಸಾಧನದ ಡಿಸ್‌ಪ್ಲೇನಲ್ಲಿ ಮಾತ್ರ ಶೇಡ್ ತೋರಿಸಿ"</item>
+    <item msgid="7795034287069726554">"ಒಂದೇ ಬಾಹ್ಯ ಡಿಸ್‌ಪ್ಲೇನಲ್ಲಿ ಸಾಧನವನ್ನು ತೋರಿಸಿ"</item>
+    <item msgid="5280431949814340475">"ಕೊನೆಯ ಕೇಂದ್ರೀಕೃತ ಡಿಸ್‌ಪ್ಲೇನಲ್ಲಿ ಸಾಧನವನ್ನು ತೋರಿಸಿ"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index a85d0cc..20b4c93 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"ಸಕ್ರಿಯವಾಗಿದೆ (ಎಡಕಿವಿಯ ಸಾಧನ ಮಾತ್ರ)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"ಸಕ್ರಿಯವಾಗಿದೆ (ಬಲಕಿವಿಯ ಸಾಧನ ಮಾತ್ರ)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"ಸಕ್ರಿಯವಾಗಿವೆ (ಎಡ ಮತ್ತು ಬಲಕಿವಿಯ ಸಾಧನಗಳು)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ಸಕ್ರಿಯವಾಗಿದೆ (ಮೀಡಿಯಾ ಮಾತ್ರ). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಮಟ್ಟ."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ಸಕ್ರಿಯವಾಗಿದೆ (ಮೀಡಿಯಾ ಮಾತ್ರ). ಎಡ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ಬಲ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ಬ್ಯಾಟರಿ ಮಟ್ಟ."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"ಕನೆಕ್ಟ್‌ ಆಗಿದೆ (ಆಡಿಯೋ ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ಬೆಂಬಲಿಸುತ್ತದೆ). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಮಟ್ಟ."</string>
@@ -241,7 +243,7 @@
     <string name="category_clone" msgid="1554511758987195974">"ಕ್ಲೋನ್"</string>
     <string name="development_settings_title" msgid="140296922921597393">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳು"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
-    <string name="development_settings_summary" msgid="8718917813868735095">"ಆ್ಯಪ್‌ ಅಭಿವೃದ್ಧಿಗಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
+    <string name="development_settings_summary" msgid="8718917813868735095">"ಆ್ಯಪ್‌ ಅಭಿವೃದ್ಧಿಗಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="development_settings_not_available" msgid="355070198089140951">"ಈ ಬಳಕೆದಾರರಿಗೆ ಡೆವಲಪರ್‌ ಆಯ್ಕೆಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="vpn_settings_not_available" msgid="2894137119965668920">"VPN ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="tethering_settings_not_available" msgid="266821736434699780">"ಟೆಥರಿಂಗ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಬಳಕೆದಾರರಿಗೆ ಲಭ್ಯವಿಲ್ಲ"</string>
@@ -361,7 +363,7 @@
     <string name="enable_linux_terminal_summary" msgid="2029479880888108902">"(ಪ್ರಾಯೋಗಿಕ) Android ನಲ್ಲಿ Linux ಟರ್ಮಿನಲ್ ಅನ್ನು ರನ್ ಮಾಡಿ"</string>
     <string name="disable_linux_terminal_disclaimer" msgid="3054320531778388231">"ನೀವು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದರೆ, Linux ಟರ್ಮಿನಲ್ ಡೇಟಾ ತೆರವುಗೊಳಿಸಲಾಗುತ್ತದೆ"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ಪರೀಕ್ಷಿಸುವಿಕೆ"</string>
-    <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP ಪರಿಶೀಲನಾ ನಡವಳಿಕೆಯನ್ನು ಹೊಂದಿಸಿ"</string>
+    <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP ಪರಿಶೀಲನಾ ನಡವಳಿಕೆಯನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ಡೀಬಗ್ ಮಾಡುವಿಕೆ"</string>
     <string name="debug_app" msgid="8903350241392391766">"ಡೀಬಗ್ ಆ್ಯಪ್‌ ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="debug_app_not_set" msgid="1934083001283807188">"ಯಾವುದೇ ಡೀಬಗ್ ಅಪ್ಲಿಕೇಶನ್‌ ಅನ್ನು ಹೊಂದಿಸಿಲ್ಲ"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ಪರಿವರ್ತನೆ ಅನಿಮೇಶನ್ ಸ್ಕೇಲ್‌"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ಅನಿಮೇಟರ್ ಅವಧಿಯ ಪ್ರಮಾಣ"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"ಮಾಧ್ಯಮಿಕ ಡಿಸ್‌ಪ್ಲೇ ಸಿಮ್ಯುಲೇಟ್‌"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"ಶೇಡ್ ಡಿಸ್‌ಪ್ಲೇ ಸ್ಥಾನ"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"ಚಟುವಟಿಕೆಗಳನ್ನು ಇರಿಸಬೇಡಿ"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ಬಳಕೆದಾರರು ಹೊರಹೋಗುತ್ತಿದ್ದಂತೆಯೇ ಚಟುವಟಿಕೆ ನಾಶಪಡಿಸು"</string>
@@ -466,7 +469,7 @@
     <string name="runningservices_settings_title" msgid="6460099290493086515">"ರನ್‌ ಆಗುತ್ತಿರುವ ಸೇವೆಗಳು"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"ಈಗ ರನ್‌ ಆಗುತ್ತಿರುವ ಸೇವೆಗಳನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ನಿಯಂತ್ರಿಸಿ"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ಹೊಂದಿಸಿ"</string>
-    <string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView ಅನುಷ್ಠಾನಗೊಳಿಸುವಿಕೆಯನ್ನು ಹೊಂದಿಸಿ"</string>
+    <string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"WebView ಅನುಷ್ಠಾನಗೊಳಿಸುವಿಕೆಯನ್ನು ಸೆಟ್ ಮಾಡಿ"</string>
     <string name="select_webview_provider_toast_text" msgid="8512254949169359848">"ಈ ಆಯ್ಕೆಯು ಇನ್ನು ಮುಂದೆ ಮಾನ್ಯವಾಗಿರುವುದಿಲ್ಲ. ಮತ್ತೊಮ್ಮೆ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="picture_color_mode" msgid="1013807330552931903">"ಚಿತ್ರ ಬಣ್ಣದ ಮೋಡ್"</string>
     <string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB ಬಳಸಿ"</string>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index 0a9663e..dd1121f 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"기기 디스플레이만(기본값)"</item>
+    <item msgid="9161645858025071955">"외부 디스플레이"</item>
+    <item msgid="114384731934682483">"포커스 기반"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"기기 디스플레이에만 음영 표시"</item>
+    <item msgid="7795034287069726554">"단일 외부 디스플레이에 기기 표시"</item>
+    <item msgid="5280431949814340475">"마지막으로 포커스된 디스플레이에 기기 표시"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 3f3fa54..084ab17 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"활성(왼쪽만)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"활성(오른쪽만)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"활성(왼쪽 및 오른쪽)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"사용 중입니다(미디어 전용). 배터리는 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>입니다."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"사용 중입니다(미디어 전용). 배터리는 왼쪽 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, 오른쪽 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>입니다."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"연결되었습니다(오디오 공유 지원). 배터리는 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>입니다."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"전환 애니메이션 배율"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 길이 배율"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"보조 디스플레이 시뮬레이션"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"음영 표시 위치"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"앱"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"활동 유지 안함"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"사용자가 종료하는 즉시 바로 제거"</string>
diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml
index f28026e..fe44fe0 100644
--- a/packages/SettingsLib/res/values-ky/arrays.xml
+++ b/packages/SettingsLib/res/values-ky/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Түзмөктүн экраны гана (демейки)"</item>
+    <item msgid="9161645858025071955">"Тышкы экран"</item>
+    <item msgid="114384731934682483">"Focus-based"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Көлөкөнү түзмөктүн экранында гана көрсөтүү"</item>
+    <item msgid="7795034287069726554">"Түзмөктү бир тышкы экранда көрсөтүү"</item>
+    <item msgid="5280431949814340475">"Түзмөктү акыркы активдүү экранда көрсөтүү"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index db55252..2d1ea867 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Иштеп жатат (сол тарап гана)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Иштеп жатат (оң тарап гана)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Иштеп жатат (сол жана оң)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Жигердүү (медиа үчүн гана). Батарея: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Жигердүү (медиа үчүн гана). Батарея: L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Туташып турат (чогуу уксаңыз болот). Батарея: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Өткөрүү анимацснн шкаласы"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Анимациянын узактыгы"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Көмөкчү экрандардын эмуляциясы"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Көлөкө экранынын абалы"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Колдонмолор"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Аракеттер сакталбасын"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Колдонуучу чыгып кетери менен бардык аракеттер өчүп калат"</string>
diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml
index 478b5d5..d9da45b4 100644
--- a/packages/SettingsLib/res/values-lo/arrays.xml
+++ b/packages/SettingsLib/res/values-lo/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"ຈໍສະແດງຜົນຂອງອຸປະກອນເທົ່ານັ້ນ (ຄ່າເລີ່ມຕົ້ນ)"</item>
+    <item msgid="9161645858025071955">"ຈໍສະແດງຜົນພາຍນອກ"</item>
+    <item msgid="114384731934682483">"ອີງຕາມການໂຟກັສ"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"ສະແດງເສດສີໃນຈໍສະແດງຜົນຂອງອຸປະກອນເທົ່ານັ້ນ"</item>
+    <item msgid="7795034287069726554">"ສະແດງອຸປະກອນໃນຈໍສະແດງຜົນພາຍນອກເຄື່ອງດຽວ"</item>
+    <item msgid="5280431949814340475">"ສະແດງອຸປະກອນໃນຈໍສະແດງຜົນທີ່ໂຟກັສຫຼ້າສຸດ"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index f60894b..ec06e5e 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"ນຳໃຊ້ຢູ່ (ຊ້າຍເທົ່ານັ້ນ)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"ນຳໃຊ້ຢູ່ (ຂວາເທົ່ານັ້ນ)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"ນຳໃຊ້ຢູ່ (ຊ້າຍ ແລະ ຂວາ)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ນຳໃຊ້ຢູ່ (ມີເດຍເທົ່ານັ້ນ). ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ນຳໃຊ້ຢູ່ (ມີເດຍເທົ່ານັ້ນ). ຊ: ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ຂ: ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"ເຊື່ອມຕໍ່ແລ້ວ (ຮອງຮັບການແບ່ງປັນສຽງ). ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ຂະໜາດສະຫຼັບອະນິເມຊັນ"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ໄລຍະເວລາອະນິເມຊັນ"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"ຈຳລອງຈໍສະແດງຜົນທີສອງ"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"ຕຳແໜ່ງການສະແດງຜົນຂອງເສດສີ"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"ແອັບ"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"ບໍ່ຕ້ອງຮັກສາການເຄື່ອນ​ໄຫວ"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ລຶບທຸກການເຄື່ອນໄຫວທັນທີທີ່ຜູ້ໃຊ້ອອກຈາກມັນ"</string>
diff --git a/packages/SettingsLib/res/values-lt/arrays.xml b/packages/SettingsLib/res/values-lt/arrays.xml
index 5d3d596..cf9b8d8 100644
--- a/packages/SettingsLib/res/values-lt/arrays.xml
+++ b/packages/SettingsLib/res/values-lt/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Tik įrenginio ekranas (numatytasis nustatymas)"</item>
+    <item msgid="9161645858025071955">"Išorinis ekranas"</item>
+    <item msgid="114384731934682483">"Pagal fokusavimą"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Rodyti šešėlį tik įrenginio ekrane"</item>
+    <item msgid="7795034287069726554">"Rodyti įrenginį viename išoriniame ekrane"</item>
+    <item msgid="5280431949814340475">"Rodyti įrenginį paskutiniame fokusuotame ekrane"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 2932d21..f0a82e0 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktyvus (tik kairiojoje pusėje)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktyvus (tik dešiniojoje pusėje)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktyvus (kairiojoje ir dešiniojoje pusėse)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktyvus (tik medija). Akumuliatorius lygis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktyvus (tik medija), akumuliatoriaus lygis kairėje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, dešinėje: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Prijungta (palaikomas garso įrašų bendrinimas). Akumuliatoriaus lygis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Animuoto perėjimo mast."</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator. trukmės skalė"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Imituoti antrin. ekranus"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Šešėlio rodymo padėtis"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Programos"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Nesaugoti veiklos"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Sunaikinti visą veiklą, kai naud. iš jos išeina"</string>
diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml
index 7626c66..92d141e 100644
--- a/packages/SettingsLib/res/values-lv/arrays.xml
+++ b/packages/SettingsLib/res/values-lv/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Tikai ierīces displejs (noklusējums)"</item>
+    <item msgid="9161645858025071955">"Ārējais displejs"</item>
+    <item msgid="114384731934682483">"Saskaņā ar fokusu"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Rādīt ēnu tikai ierīces displejā"</item>
+    <item msgid="7795034287069726554">"Rādīt ierīci vienā ārējā displejā"</item>
+    <item msgid="5280431949814340475">"Rādīt ierīci pēdējā fokusētajā displejā"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 2f497fb..47fe2d9 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Ierīce aktīva (tikai kreisā auss)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Ierīce aktīva (tikai labā auss)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Ierīces aktīvas (kreisā un labā auss)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktīvs (tikai multividei). Akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktīvs (tikai multividei). Akumulatora uzlādes līmenis kreisajā austiņā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, labajā austiņā: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Izveidots savienojums (atbalsta audio kopīgošanu). Akumulatora uzlādes līmenis: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Pārejas animācijas mērogs"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animācijas ilguma mērogs"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulēt sekundāros ekr."</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Ēnas parādīšanas pozīcija"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Lietotnes"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Nesaglabāt darbības"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Iznīcināt katru darbību, kad lietotājs to pārtrauc"</string>
diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml
index f1a02bb..8e9bb21 100644
--- a/packages/SettingsLib/res/values-mk/arrays.xml
+++ b/packages/SettingsLib/res/values-mk/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Само на екранот на уредот (стандардно)"</item>
+    <item msgid="9161645858025071955">"Надворешен екран"</item>
+    <item msgid="114384731934682483">"Засновано на фокус"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Прикажувај сенка само на екранот на уредот"</item>
+    <item msgid="7795034287069726554">"Прикажувај сенка на еден надворешен екран"</item>
+    <item msgid="5280431949814340475">"Прикажувај сенка на последниот фокусиран екран"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"стандарден_екран"</item>
+    <item msgid="774789415968826925">"кој_било_надворешен_екран"</item>
+    <item msgid="7880769915418638436">"последен_допир_на_статусната_лента"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 54d1ff1..a8c8d83 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Активно (само лево)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Активно (само десно)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Активно (лево и десно)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Активно (само аудиовизуелни содржини). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Активно (само аудиовизуелни содржини). Л: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> батерија, Д: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерија."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Поврзано (поддржува споделување аудио). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерија."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Брзина на преодни анимации"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Брзина на општи анимации"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Симул. секундарен екран"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Позиција на екранот за сенка"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Апликации"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Не чувај активности"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Уништи ја секоја активност штом корисникот ќе ја напушти"</string>
diff --git a/packages/SettingsLib/res/values-ml/arrays.xml b/packages/SettingsLib/res/values-ml/arrays.xml
index 5e535d3..4b8dbce 100644
--- a/packages/SettingsLib/res/values-ml/arrays.xml
+++ b/packages/SettingsLib/res/values-ml/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"ഉപകരണ ഡിസ്പ്ലേ മാത്രം (ഡിഫോൾട്ട്)"</item>
+    <item msgid="9161645858025071955">"ബാഹ്യ ഡിസ്പ്ലേ"</item>
+    <item msgid="114384731934682483">"ഫോക്കസ്-അടിസ്ഥാനമാക്കിയുള്ളത്"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"ഉപകരണ ഡിസ്പ്ലേയിൽ മാത്രം ഷെയ്‌ഡ് കാണിക്കുക"</item>
+    <item msgid="7795034287069726554">"ഒരൊറ്റ ബാഹ്യ ഡിസ്പ്ലേയിൽ ഉപകരണം കാണിക്കുക"</item>
+    <item msgid="5280431949814340475">"അവസാനം ഫോക്കസ് ചെയ്ത ഡിസ്പ്ലേയിൽ ഉപകരണം കാണിക്കുക"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 19c380b..859c67e 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"സജീവമാണ് (ഇടതുഭാഗത്ത് മാത്രം)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"സജീവമാണ് (വലതുഭാഗത്ത് മാത്രം)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"സജീവമാണ് (ഇടതുഭാഗത്തും വലതുഭാഗത്തും)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"സജീവം (മീഡിയ മാത്രം). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ബാറ്ററി."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"സജീവം (മീഡിയ മാത്രം). ഇടതുവശത്ത്: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ബാറ്ററി, വലതുവശത്ത്: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ബാറ്ററി."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"കണക്റ്റ് ചെയ്തു (ഓഡിയോ പങ്കിടൽ പിന്തുണയ്ക്കുന്നു). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ബാറ്ററി."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ട്രാൻസിഷൻ ആനിമേഷൻ സ്‌കെയിൽ"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ആനിമേറ്റർ ദൈർഘ്യ സ്‌കെയിൽ"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"രണ്ടാം ഡിസ്‌പ്ലേകൾ പ്രവർത്തിപ്പിക്കുക"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"ഷെയ്‌ഡ് ഡിസ്പ്ലേ സ്ഥാനം"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"ആപ്പുകൾ"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"പ്രവർത്തനങ്ങൾ സൂക്ഷിക്കരുത്"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ഉപയോക്താവ് ഉപേക്ഷിക്കുന്നതിനനുസരിച്ച് എല്ലാ പ്രവർത്തനങ്ങളും നശിപ്പിക്കുക"</string>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index 84c707f..5d5b8f9 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Зөвхөн төхөөрөмжийн дэлгэц (өгөгдмөл)"</item>
+    <item msgid="9161645858025071955">"Гаднын дэлгэц"</item>
+    <item msgid="114384731934682483">"Төвлөрөлд тулгуурласан"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Зөвхөн төхөөрөмж дээрх дэлгэцэд сүүдрийг харуулах"</item>
+    <item msgid="7795034287069726554">"Зөвхөн гаднын нэг дэлгэц дээр төхөөрөмжийг харуулах"</item>
+    <item msgid="5280431949814340475">"Сүүлд төвлөрсөн дэлгэц дээр төхөөрөмжийг харуулах"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 0e3408e..c61bcde 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Идэвхтэй (зөвхөн зүүн тал)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Идэвхтэй (зөвхөн баруун тал)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Идэвхтэй (зүүн, баруун тал)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Идэвхтэй (зөвхөн медиа). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батарей."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Идэвхтэй (зөвхөн медиа). З: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Б: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батарей."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Холбогдсон (аудио хуваалцахыг дэмждэг). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батарей."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Шилжилтийн анимацийн масштаб"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Анимацийн хугацааны масштаб"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Хоёр дахь дэлгэцийн симуляци хийх"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Сүүдрийн дэлгэцийн байрлал"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Апп"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Үйлдлүүдийг хадгалахгүй"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Үйлдэл бүрийг хэрэглэгч орхимогц нь устгах"</string>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index 9286e77..2fd2058 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"फक्त डिव्हाइस डिस्प्ले (डीफॉल्ट)"</item>
+    <item msgid="9161645858025071955">"बाह्य डिस्प्ले"</item>
+    <item msgid="114384731934682483">"फोकसवर आधारित"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"फक्त डिव्हाइस डिस्प्लेवर शेड दाखवा"</item>
+    <item msgid="7795034287069726554">"एकल बाह्य डिस्प्लेवर डिव्हाइस दाखवा"</item>
+    <item msgid="5280431949814340475">"शेवटच्या फोकस केलेल्या डिस्प्लेवर डिव्हाइस दाखवा"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 9b7c99c..654b447 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"अ‍ॅक्टिव्ह आहे (फक्त डावे)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"अ‍ॅक्टिव्ह आहे (फक्त उजवे)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"अ‍ॅक्टिव्ह आहे (डावे आणि उजवे)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"अ‍ॅक्टिव्ह आहे (फक्त मीडिया). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ॲक्टिव्ह आहे (फक्त मीडिया). डावीकडे: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> बॅटरी, उजवीकडे: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बॅटरी."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"कनेक्ट केले आहे (ऑडिओ शेअरिंगला सपोर्ट करते). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ट्रांझिशन ॲनिमेशन स्केल"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ॲनिमेटर कालावधी स्केल"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"दुय्यम डिस्प्ले सिम्युलेट करा"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"शेड डिस्प्लेशी संबंधित स्थिती"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"अ‍ॅप्स"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"ॲक्टिव्हिटी ठेवू नका"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"वापरकर्त्याने प्रत्येक ॲक्टिव्हिटी सोडताच ती नष्ट करा"</string>
diff --git a/packages/SettingsLib/res/values-ms/arrays.xml b/packages/SettingsLib/res/values-ms/arrays.xml
index a159282..7b6cbe1 100644
--- a/packages/SettingsLib/res/values-ms/arrays.xml
+++ b/packages/SettingsLib/res/values-ms/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Paparan peranti sahaja (Lalai)"</item>
+    <item msgid="9161645858025071955">"Paparan luaran"</item>
+    <item msgid="114384731934682483">"Berasaskan fokus"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Tunjukkan rona warna pada paparan peranti sahaja"</item>
+    <item msgid="7795034287069726554">"Tunjukkan peranti pada satu paparan luaran"</item>
+    <item msgid="5280431949814340475">"Tunjukkan peranti pada paparan terakhir yang difokuskan"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 7c5d3f7..fcb5d6e 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktif (kiri sahaja)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktif (kanan sahaja)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktif (kiri dan kanan)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktif (media sahaja). Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktif (media sahaja), L: Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Disambungkan (menyokong perkongsian audio). Bateri <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animasi peralihan"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala tempoh juruanimasi"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulasikan paparan kedua"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Kedudukan paparan rona warna"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplikasi"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Jangan simpan aktiviti"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Hapus aktiviti selepas ditinggalkan oleh pengguna"</string>
diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml
index e795689..71a1c7c 100644
--- a/packages/SettingsLib/res/values-my/arrays.xml
+++ b/packages/SettingsLib/res/values-my/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"စက်ဖန်သားပြင် သီးသန့် (မူရင်း)"</item>
+    <item msgid="9161645858025071955">"ပြင်ပဖန်သားပြင်"</item>
+    <item msgid="114384731934682483">"ပြသမှုအခြေပြု"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"စက်ဖန်သားပြင်တွင်သာ အရိပ်ပြပါ"</item>
+    <item msgid="7795034287069726554">"ပြင်ပဖန်သားပြင်တစ်ခုတွင် စက်ကိုပြပါ"</item>
+    <item msgid="5280431949814340475">"နောက်ဆုံးပြသထားသော ဖန်သားပြင်တွင် စက်ကိုပြပါ"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"မူရင်းဖန်သားပြင်"</item>
+    <item msgid="774789415968826925">"မည်သည့်ပြင်ပဖန်သားပြင်မဆို"</item>
+    <item msgid="7880769915418638436">"အခြေအနေပြဘား နောက်ဆုံးထိတွေ့မှု"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 0bd6ca6..4826c49 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"သုံးနေသည် (ဘယ်ဘက်သီးသန့်)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"သုံးနေသည် (ညာဘက်သီးသန့်)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"သုံးနေသည် (ဘယ်နှင့်ညာ)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"အသုံးပြုနေသည် (မီဒီယာသီးသန့်)။ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>။"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"အသုံးပြုနေသည် (မီဒီယာသီးသန့်)။ ဘက်ထရီ L- <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>၊ R- <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>။"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"ချိတ်ဆက်ထားသည် (အော်ဒီယို မျှဝေခြင်း ပံ့ပိုးသည်)။ ဘက်ထရီ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>။"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"သက်ဝင်အသွင်ပြောင်းခြင်း"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"လှုပ်ရှားမှုကြာချိန်စကေး"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"ဆင့်ပွားမျက်နှာပြင် အသွင်ဆောင်ခြင်း"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"အရိပ်ပြကွက် တည်နေရာ"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"အက်ပ်များ"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"ဆောင်ရွက်မှုများကို သိမ်းမထားပါနှင့်"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"သုံးသူထွက်သွားသည်နှင့် လုပ်ဆောင်ချက်များ ဖျက်ရန်"</string>
diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml
index c456ae1..8d52693 100644
--- a/packages/SettingsLib/res/values-nb/arrays.xml
+++ b/packages/SettingsLib/res/values-nb/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Bare enhetsskjermen (standard)"</item>
+    <item msgid="9161645858025071955">"Ekstern skjerm"</item>
+    <item msgid="114384731934682483">"Fokusbasert"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Vis skyggen bare på enhetsskjermen"</item>
+    <item msgid="7795034287069726554">"Vis enheten på én ekstern skjerm"</item>
+    <item msgid="5280431949814340475">"Vis enheten på den sist fokuserte skjermen"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"Standardskjerm"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index ab14606..e7be3c9 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktiv (bare venstre)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktiv (bare høyre)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktiv (venstre og høyre)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiv (bare medieinnhold) <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiv (bare medieinnhold). V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batteri, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Tilkoblet (støtter lyddeling). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Animasjonsskala for overgang"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Varighetsskala for animasjoner"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulering av sekundærskjermer"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Plassering av skyggeskjermen"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Apper"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ikke behold aktiviteter"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Fjern hver aktivitet så fort brukeren forlater den"</string>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index d2c3729..cd8448f 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"२"</item>
     <item msgid="4779928470672877922">"३"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"डिभाइसको डिस्प्ले मात्र (डिफल्ट)"</item>
+    <item msgid="9161645858025071955">"बाह्य डिस्प्ले"</item>
+    <item msgid="114384731934682483">"फोकसमा आधारित"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"यो सेड डिभाइसकै डिस्प्लेमा मात्र देखाउनुहोस्"</item>
+    <item msgid="7795034287069726554">"यो डिभाइस एकल बाह्य डिस्प्लेमा देखाउनुहोस्"</item>
+    <item msgid="5280431949814340475">"यो डिभाइस पछिल्लो पटक फोकस गरिएको डिस्प्लेमा देखाउनुहोस्"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 50665f6..0478d9c 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"सक्रिय छ (बायाँ मात्र)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"सक्रिय छ (दायाँ मात्र)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"सक्रिय छ (दायाँ र बायाँ)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"सक्रिय छ (मिडिया मात्र)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ब्याट्री।"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"सक्रिय छ (मिडिया मात्र)। बायाँ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, दायाँ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ब्याट्री।"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"कनेक्ट गरिएको छ (अडियो सेयर गर्न मिल्छ)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ब्याट्री।"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"संक्रमण एनिमेसन स्केल"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"एनिमेसनको अवधि मापन"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"सहायक डिस्प्लेको नक्कल गर्नुहोस्"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"सेड देखाइने स्थिति"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"एपहरू"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"गतिविधि नराखियोस्"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"प्रयोगकर्ता कुनै गतिविधिबाट बाहिरिने बित्तिकै उक्त गतिविधि अन्त्य गर्नुहोस्"</string>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index 4451c93..d92b806 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Alleen apparaatscherm (standaard)"</item>
+    <item msgid="9161645858025071955">"Extern scherm"</item>
+    <item msgid="114384731934682483">"Op focus gebaseerd"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Alleen paneel tonen op apparaatscherm"</item>
+    <item msgid="7795034287069726554">"Apparaat tonen op één extern scherm"</item>
+    <item msgid="5280431949814340475">"Apparaat tonen op laatste gefocuste scherm"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 035c2d9..bae7bb9 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Actief (alleen links)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Actief (alleen rechts)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Actief (links en rechts)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Actief (alleen media). Batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Actief (alleen media), L: batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Verbonden (ondersteunt audio delen), batterijniveau <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Overgangs­animatieschaal"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Duur van animatieschaal"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Secundaire displays simuleren"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Positie van paneelweergave"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Activiteiten niet opslaan"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Wis activiteit zodra de gebruiker ermee stopt"</string>
diff --git a/packages/SettingsLib/res/values-or/arrays.xml b/packages/SettingsLib/res/values-or/arrays.xml
index 37e5071..f9beb8a 100644
--- a/packages/SettingsLib/res/values-or/arrays.xml
+++ b/packages/SettingsLib/res/values-or/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"କେବଳ ଡିଭାଇସ ଡିସପ୍ଲେ (ଡିଫଲ୍ଟ)"</item>
+    <item msgid="9161645858025071955">"ଏକ୍ସଟର୍ନଲ ଡିସପ୍ଲେ"</item>
+    <item msgid="114384731934682483">"ଫୋକସ-ଆଧାରିତ"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"କେବଳ ଡିଭାଇସରେ ଡିସପ୍ଲେ ସେଡ ଦେଖାନ୍ତୁ"</item>
+    <item msgid="7795034287069726554">"ସିଙ୍ଗଲ ଏକ୍ସଟର୍ନଲ ଡିସପ୍ଲେରେ ଡିଭାଇସ ଦେଖାନ୍ତୁ"</item>
+    <item msgid="5280431949814340475">"ଫୋକସ କରାଯାଇଥିବା ଗତ ଡିସପ୍ଲେରେ ଡିଭାଇସ ଦେଖାନ୍ତୁ"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 8942737..7b8f3cc 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"ସକ୍ରିୟ (କେବଳ ବାମ)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"ସକ୍ରିୟ (କେବଳ ଡାହାଣ)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"ସକ୍ରିୟ (ବାମ ଏବଂ ଡାହାଣ)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ସକ୍ରିୟ (କେବଳ ମିଡିଆ)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ବେଟେରୀ।"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ସକ୍ରିୟ (କେବଳ ମିଡିଆ)। ବାମ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ଡାହାଣ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ବେଟେରୀ।"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"କନେକ୍ଟ କରାଯାଇଛି (ଅଡିଓ ସେୟାରିଂକୁ ସପୋର୍ଟ କରେ)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ବେଟେରୀ।"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ଟ୍ରାଞ୍ଜିସନ୍‌ ଆନିମେସନ୍‌ ସ୍କେଲ୍‌"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ଆନିମେଟର୍‌ ଅବଧି ସ୍କେଲ୍‌"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"ସେକେଣ୍ଡାରୀ ଡିସ୍‌ପ୍ଲେ ସିମୁଲେଟ୍ କରନ୍ତୁ"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"ସେଡ ଡିସପ୍ଲେ ସ୍ଥିତି"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"ଆପ୍ସ"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"କାର୍ଯ୍ୟକଳାପଗୁଡ଼ିକୁ ରଖନ୍ତୁ ନାହିଁ"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ୟୁଜର୍ ଏହାକୁ ଛାଡ଼ିବା କ୍ଷଣି ସମସ୍ତ କାର୍ଯ୍ୟକଳାପ ନଷ୍ଟ କରିଦିଅନ୍ତୁ"</string>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index 3cb0f50..1e7f055 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"ਸਿਰਫ਼ ਡੀਵਾਈਸ ਦੀ ਡਿਸਪਲੇ (ਪੂਰਵ-ਨਿਰਧਾਰਿਤ)"</item>
+    <item msgid="9161645858025071955">"ਬਾਹਰੀ ਡਿਸਪਲੇ"</item>
+    <item msgid="114384731934682483">"ਫੋਕਸ-ਆਧਾਰਿਤ"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"ਸਿਰਫ਼ ਡੀਵਾਈਸ ਦੀ ਡਿਸਪਲੇ \'ਤੇ ਸ਼ੇਡ ਦਿਖਾਓ"</item>
+    <item msgid="7795034287069726554">"ਇਕਹਿਰੀ ਬਾਹਰੀ ਡਿਸਪਲੇ \'ਤੇ ਡੀਵਾਈਸ ਦਿਖਾਓ"</item>
+    <item msgid="5280431949814340475">"ਫੋਕਸ ਕੀਤੀ ਗਈ ਪਿਛਲੀ ਡਿਸਪਲੇ \'ਤੇ ਡੀਵਾਈਸ ਦਿਖਾਓ"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 14e87aa..7e2a50f 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"ਕਿਰਿਆਸ਼ੀਲ (ਸਿਰਫ਼ ਖੱਬਾ)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"ਕਿਰਿਆਸ਼ੀਲ (ਸਿਰਫ਼ ਸੱਜਾ)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"ਕਿਰਿਆਸ਼ੀਲ (ਖੱਬਾ ਅਤੇ ਸੱਜਾ)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ਕਿਰਿਆਸ਼ੀਲ (ਸਿਰਫ਼ ਮੀਡੀਆ)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ਬੈਟਰੀ।"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ਕਿਰਿਆਸ਼ੀਲ (ਸਿਰਫ਼ ਮੀਡੀਆ)। ਖੱਬੇ ਪਾਸੇ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ਸੱਜੇ ਪਾਸੇ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ਬੈਟਰੀ।"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"ਕਨੈਕਟ ਕੀਤਾ (ਆਡੀਓ ਸਾਂਝਾਕਰਨ ਦਾ ਸਮਰਥਨ ਕਰਦਾ ਹੈ)। <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ਬੈਟਰੀ।"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ਟ੍ਰਾਂਜ਼ਿਸ਼ਨ ਐਨੀਮੇਸ਼ਨ ਸਕੇਲ"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ਐਨੀਮੇਟਰ ਮਿਆਦ ਸਕੇਲ"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"ਸੈਕੰਡਰੀ ਡਿਸਪਲੇ ਨੂੰ ਸਿਮੂਲੇਟ ਕਰੋ"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"ਸ਼ੇਡ ਦਿਖਣ ਦੀ ਸਥਿਤੀ"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"ਐਪਾਂ"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"ਸਰਗਰਮੀਆਂ ਨਾ ਰੱਖੋ"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ਹਰੇਕ ਸਰਗਰਮੀ ਨਸ਼ਟ ਕਰੋ, ਜਿਵੇਂ ਹੀ ਵਰਤੋਂਕਾਰ ਇਸਨੂੰ ਛੱਡੇ"</string>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index 9c25aaa..a9892b3 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Tylko wyświetlanie na urządzeniu (domyślnie)"</item>
+    <item msgid="9161645858025071955">"Wyświetlacz zewnętrzny"</item>
+    <item msgid="114384731934682483">"Na podstawie zaznaczenia"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Pokaż cień tylko na wyświetlaczu urządzenia"</item>
+    <item msgid="7795034287069726554">"Pokaż urządzenie na pojedynczym wyświetlaczu zewnętrznym"</item>
+    <item msgid="5280431949814340475">"Pokaż urządzenie na ostatnim aktywnym wyświetlaczu"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index eaa12bd..397cb82 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktywne (tylko lewa strona)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktywne (tylko prawa strona)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktywne (lewa i prawa strona)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktywne (tylko multimedia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> naładowania baterii."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktywne (tylko multimedia), lewa: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, prawa: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> naładowania baterii."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Połączone (obsługa udostępniania dźwięku), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> naładowania baterii."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animacji przejścia"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala długości animacji"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Symuluj ekrany dodatkowe"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Pozycja wyświetlania cienia"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplikacje"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Nie zachowuj działań"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Przerwij każde działanie, gdy użytkownik je porzuci"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
index bb18c47..35aa3b0 100644
--- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Somente a tela do dispositivo (padrão)"</item>
+    <item msgid="9161645858025071955">"Tela externa"</item>
+    <item msgid="114384731934682483">"Com base no foco"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Mostrar sombra apenas na tela do dispositivo"</item>
+    <item msgid="7795034287069726554">"Mostrar o dispositivo em uma única tela externa"</item>
+    <item msgid="5280431949814340475">"Mostrar o dispositivo na última tela focada"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index afa7129..273c84d 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Ativo (apenas o esquerdo)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Ativo (apenas o direito)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Ativo (esquerdo e direito)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Ativo (apenas mídia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Ativo (apenas mídia). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (aceita compartilhamento de áudio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala anim. de transição"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala duração Animator"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simular telas secundárias"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Posição da sombra do dispositivo"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Não manter atividades"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Destruir todas as atividades quando o usuário sair"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
index 50a90eb..2f870bf 100644
--- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Apenas no ecrã do dispositivo (predefinição)"</item>
+    <item msgid="9161645858025071955">"Ecrã externo"</item>
+    <item msgid="114384731934682483">"Com base no foco"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Mostrar a sombra apenas no ecrã do dispositivo"</item>
+    <item msgid="7795034287069726554">"Mostrar o dispositivo num único ecrã externo"</item>
+    <item msgid="5280431949814340475">"Mostrar o dispositivo no último ecrã focado"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 986467a..9d56b43 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -110,6 +110,7 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Ativo (apenas esquerdo)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Ativo (apenas direito)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Ativo (esquerdo e direito)"</string>
+    <string name="bluetooth_hearing_device_ambient_error" msgid="6035857289108813878">"Não foi possível atualizar o ambiente"</string>
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Ativo (apenas para multimédia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Ativo (apenas para multimédia). E: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Ligado (suporta partilha de áudio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
@@ -423,6 +424,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animação de transição"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duração de animação"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simular apresentações secundárias"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Posição da sombra no ecrã"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Não manter atividades"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Destruir atividades assim que o utilizador sair"</string>
diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml
index bb18c47..35aa3b0 100644
--- a/packages/SettingsLib/res/values-pt/arrays.xml
+++ b/packages/SettingsLib/res/values-pt/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Somente a tela do dispositivo (padrão)"</item>
+    <item msgid="9161645858025071955">"Tela externa"</item>
+    <item msgid="114384731934682483">"Com base no foco"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Mostrar sombra apenas na tela do dispositivo"</item>
+    <item msgid="7795034287069726554">"Mostrar o dispositivo em uma única tela externa"</item>
+    <item msgid="5280431949814340475">"Mostrar o dispositivo na última tela focada"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index afa7129..273c84d 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Ativo (apenas o esquerdo)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Ativo (apenas o direito)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Ativo (esquerdo e direito)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Ativo (apenas mídia). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Ativo (apenas mídia). Lado esquerdo: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> de bateria. Lado direito: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> de bateria."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectado (aceita compartilhamento de áudio). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> de bateria."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala anim. de transição"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala duração Animator"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simular telas secundárias"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Posição da sombra do dispositivo"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Não manter atividades"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Destruir todas as atividades quando o usuário sair"</string>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index c29a752..dba734c 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Numai pe ecranul dispozitivului (prestabilit)"</item>
+    <item msgid="9161645858025071955">"Ecran extern"</item>
+    <item msgid="114384731934682483">"În funcție de focalizare"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Afișează umbra doar pe ecranul dispozitivului"</item>
+    <item msgid="7795034287069726554">"Afișează dispozitivul pe un singur ecran extern"</item>
+    <item msgid="5280431949814340475">"Afișează dispozitivul pe ultimul ecran focalizat"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index b64047c..1d77583 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Activ (numai stânga)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Activ (numai dreapta)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Activ (stânga și dreapta)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Activ (numai pentru conținut media). Nivelul bateriei <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Activ (numai pentru conținut media): nivelul bateriei din stânga: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, nivelul bateriei din dreapta: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Conectat (acceptă permiterea accesului la audio). Nivelul bateriei: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Scară tranziție animații"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Scară durată Animator"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulează afișaje secundare"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Poziția de afișare a umbrei"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplicații"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Nu păstra activitățile"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Elimină activitățile imediat ce utilizatorul le închide"</string>
diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml
index e26b1a6..f0782eb 100644
--- a/packages/SettingsLib/res/values-ru/arrays.xml
+++ b/packages/SettingsLib/res/values-ru/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Только экран устройства (по умолчанию)"</item>
+    <item msgid="9161645858025071955">"Внешний дисплей"</item>
+    <item msgid="114384731934682483">"Активный дисплей"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Показывать тень только на экране устройства"</item>
+    <item msgid="7795034287069726554">"Показывать устройство на одном внешнем дисплее"</item>
+    <item msgid="5280431949814340475">"Показывать устройство на последнем активном дисплее"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 8c9ecb1..d697780 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Используется (только левый)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Используется (только правый)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Используется (левый и правый)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Используется (только для медиа), заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Используется (только для медиа), заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (Л), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (П)."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Подключено (поддерживается отправка аудио), заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Анимация переходов"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Длительность анимации"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Эмуляция доп. экранов"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Положение тени"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Приложения"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Вытеснение фоновых Activity"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Удалять все Activity после выхода пользователя"</string>
diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml
index dea89e5..855bbc9 100644
--- a/packages/SettingsLib/res/values-si/arrays.xml
+++ b/packages/SettingsLib/res/values-si/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"උපාංග සංදර්ශකය පමණි (පෙරනිමි)"</item>
+    <item msgid="9161645858025071955">"බාහිර සංදර්ශකය"</item>
+    <item msgid="114384731934682483">"නාභිගත කිරීම-පාදක"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"උපාංග සංදර්ශකයේ පමණක් සෙවන පෙන්වන්න"</item>
+    <item msgid="7795034287069726554">"උපාංගය තනි බාහිර සංදර්ශකයක පෙන්වන්න"</item>
+    <item msgid="5280431949814340475">"අවසන් වරට නාභිගත කළ සංදර්ශකයේ උපාංගය පෙන්වන්න"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 6c9abfb..df22ba7 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"සක්‍රිය (වම පමණි)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"සක්‍රිය (දකුණ පමණි)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"සක්‍රිය (වම සහ දකුණ)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ක්‍රියාත්මකයි (මාධ්‍ය පමණයි). බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ක්‍රියාත්මකයි (මාධ්‍ය පමණයි), බැටරිය ව: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ද: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"සම්බන්‍ධයි (ශ්‍රව්‍ය බෙදා ගැනීමට සහය දක්වයි). බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"සංක්‍රමණ සජීවන පරිමාණය"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"සජීවක කාල පරාස පරිමාණය"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"ද්විතියික දර්ශනය අඟවන්න"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"සෙවන සංදර්ශක ස්ථානය"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"යෙදුම්"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"ක්‍රියාකාරකම් තබාගන්න එපා"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"පරිශීලකයා ඉවත් වුන විගසම සෑම ක්‍රියාකාරකමක්ම විනාශ කරන්න"</string>
diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml
index 12adda5..3473e28 100644
--- a/packages/SettingsLib/res/values-sk/arrays.xml
+++ b/packages/SettingsLib/res/values-sk/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Iba obrazovka zariadenia (predvolené)"</item>
+    <item msgid="9161645858025071955">"Externá obrazovka"</item>
+    <item msgid="114384731934682483">"Na základe označenia"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Zobraziť panel iba na obrazovke zariadenia"</item>
+    <item msgid="7795034287069726554">"Zobraziť zariadenie na jednej externej obrazovke"</item>
+    <item msgid="5280431949814340475">"Zobraziť zariadenie na poslednej označenej obrazovke"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 05c7442..7af3825 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktívne (iba ľavé)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktívne (iba pravé)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktívne (ľavé aj pravé)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktívne (iba médiá). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batérie."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktívne (iba médiá). Ľ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batérie, P: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batérie."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Pripojené (podporuje zdieľanie zvuku). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batérie."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Mierka animácie premeny"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Mierka dĺžky animácie"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulovať sekundárne obrazovky"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Umiestnenie zobrazenia panela"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplikácie"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Neuchovávať aktivity"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Zničiť každú aktivitu, hneď ako ju používateľ ukončí"</string>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index bd35c82..c3bf79c 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Prikaz samo v napravi (privzeto)"</item>
+    <item msgid="9161645858025071955">"Zunanji zaslon"</item>
+    <item msgid="114384731934682483">"Na podlagi fokusa"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Prikaz podokna samo na zaslonu naprave"</item>
+    <item msgid="7795034287069726554">"Prikaz naprave na enem zunanjem zaslonu"</item>
+    <item msgid="5280431949814340475">"Prikaz naprave na zadnjem zaslonu s fokusom"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index c0e4f81..e82feb4 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktivno (samo levo)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktivno (samo desno)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktivno (levo in desno)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktivno (samo predstavnost). Baterija: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktivno (samo predstavnost), baterija – L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, D: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Povezano (podpira deljenje zvoka), baterija: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Merilo animacije prehoda"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Merilo trajanja animacije"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simuliraj sekundarne zaslone"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Položaj prikaza podokna"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplikacije"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ne obdrži dejavnosti"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Uniči vsako dejavnost, ko uporabnik preneha z njo."</string>
diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml
index bd03199..7136bf75 100644
--- a/packages/SettingsLib/res/values-sq/arrays.xml
+++ b/packages/SettingsLib/res/values-sq/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Vetëm ekrani i pajisjes (parazgjedhja)"</item>
+    <item msgid="9161645858025071955">"Ekrani i jashtëm"</item>
+    <item msgid="114384731934682483">"Bazuar te fokusi"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Shfaq hijen vetëm në ekranin e pajisjes"</item>
+    <item msgid="7795034287069726554">"Shfaq pajisjen në një ekran të vetëm të jashtëm"</item>
+    <item msgid="5280431949814340475">"Shfaq pajisjen në ekranin e fundit të fokusuar"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 2676d0e..f857309 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktive (vetëm majtas)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktive (vetëm djathtas)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktive (majtas dhe djathtas)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiv (vetëm për media). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> bateri."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiv (vetëm për media). Majtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> bateri, djathtas: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> bateri."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Lidhur (mbështet ndarjen e audios). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> bateri."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Animacioni kalimtar"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Kohëzgjatja e animatorit"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulo ekranet dytësore"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Pozicioni i shfaqjes së hijes"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Aplikacionet"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Mos i ruaj aktivitetet"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Fshi çdo aktivitet sapo të largohet përdoruesi"</string>
diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml
index 1ee7fc0..84d0a7e 100644
--- a/packages/SettingsLib/res/values-sr/arrays.xml
+++ b/packages/SettingsLib/res/values-sr/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Приказ само на уређају (подразумевано)"</item>
+    <item msgid="9161645858025071955">"Спољни екран"</item>
+    <item msgid="114384731934682483">"Засновано на фокусу"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Прикажи сенку само на екрану уређаја"</item>
+    <item msgid="7795034287069726554">"Прикажи уређај на једном спољном екрану"</item>
+    <item msgid="5280431949814340475">"Прикажи уређај на последњем екрану у фокусу"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 8fce0a0..ad15dd4 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Активно (само лево)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Активно (само десно)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Активно (лево и десно)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Активно (само за медије). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерије."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Активно (само за медије). Лево: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, десно: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> батерије."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Повезано (подржава дељење звука), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> батерије."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Размера анимације прелаза"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Аниматорова размера трајања"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Симулирај секундарне екране"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Положај сенке на екрану"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Апликације"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Не чувај активности"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Уништава сваку активност чим је корисник напусти"</string>
diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml
index 3a344ce..c69f01e 100644
--- a/packages/SettingsLib/res/values-sv/arrays.xml
+++ b/packages/SettingsLib/res/values-sv/arrays.xml
@@ -288,4 +288,15 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+    <!-- no translation found for shade_display_awareness_entries:0 (816770658383209617) -->
+    <!-- no translation found for shade_display_awareness_entries:1 (9161645858025071955) -->
+    <!-- no translation found for shade_display_awareness_entries:2 (114384731934682483) -->
+    <!-- no translation found for shade_display_awareness_summaries:0 (2964753205732912921) -->
+    <!-- no translation found for shade_display_awareness_summaries:1 (7795034287069726554) -->
+    <!-- no translation found for shade_display_awareness_summaries:2 (5280431949814340475) -->
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index c7ce0f8..7f172db 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktiv (endast vänster)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktiv (endast höger)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktiv (vänster och höger)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktiv (endast media). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktiv (endast media). V: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, H: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Ansluten (ljuddelning stöds). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri."</string>
@@ -423,6 +425,8 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala – övergångsanimering"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Längdskala för Animator"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simulera sekundär skärm"</string>
+    <!-- no translation found for shade_display_awareness_title (8000009404669495876) -->
+    <skip />
     <string name="debug_applications_category" msgid="5394089406638954196">"Appar"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Behåll inte aktiviteter"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Förstör aktiviteter så fort användaren lämnar dem"</string>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index a75c6f9..145b56c 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Kwenye skrini ya kifaa pekee (Chaguomsingi)"</item>
+    <item msgid="9161645858025071955">"Skrini ya nje"</item>
+    <item msgid="114384731934682483">"Inayoangaziwa"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Onyesha kiwango kwenye skrini ya kifaa pekee"</item>
+    <item msgid="7795034287069726554">"Onyesha kifaa kwenye skrini moja ya nje"</item>
+    <item msgid="5280431949814340475">"Onyesha kifaa kwenye skrini ya mwisho iliyoangaziwa"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 3bee28a..bf95f4e 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Inatumika (kushoto pekee)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Inatumika (kulia pekee)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Inatumika (kushoto na kulia)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Inatumika (maudhui pekee). Chaji ya betri imefika <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Inatumika (maudhui pekee), Kushoto: chaji ya betri imefika <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Kulia: chaji ya betri imefika <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Imeunganishwa (inaweza kutumia kipengele cha kusikiliza pamoja). Chaji imefika <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Mageuzi ya kipimo cha uhuishaji"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Mizani ya muda wa uhuishaji"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Iga maonyesho mbadala"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Nafasi ya kiwango kwenye skrini"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Programu"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Usihifadhi shughuli"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Haribu kila shughuli pindi tu mtumiaji anapoondoka"</string>
diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml
index ade1db0..6881289 100644
--- a/packages/SettingsLib/res/values-ta/arrays.xml
+++ b/packages/SettingsLib/res/values-ta/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"சாதனக் காட்சி மட்டும் (இயல்பு)"</item>
+    <item msgid="9161645858025071955">"வெளிப்புறக் காட்சி"</item>
+    <item msgid="114384731934682483">"ஃபோகஸ் அடிப்படையிலானது"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"சாதனக் காட்சியில் மட்டும் ஷேடைக் காட்டும்"</item>
+    <item msgid="7795034287069726554">"ஒற்றை வெளிப்புறக் காட்சியில் சாதனத்தைக் காட்டும்"</item>
+    <item msgid="5280431949814340475">"கடைசியாக ஃபோகஸ் செய்யப்பட்ட காட்சியில் சாதனத்தைக் காட்டும்"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 289947e..24c2244 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"செயலில் உள்ளது (இடதுபுறம் மட்டும்)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"செயலில் உள்ளது (வலதுபுறம் மட்டும்)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"செயலில் உள்ளது (இடது மற்றும் வலதுபுறம்)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"செயலிலுள்ளது (மீடியா மட்டும்). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> பேட்டரி."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"செயலிலுள்ளது (மீடியா மட்டும்). இடது பேட்டரி: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, வலது பேட்டரி: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"இணைக்கப்பட்டுள்ளது (ஆடியோ பகிர்வை ஆதரிக்கிறது). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> பேட்டரி."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"அனிமேஷன் மாற்றத்தின் வேகம்"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"அனிமேட்டர் கால அளவு"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"இரண்டாம்நிலைக் காட்சிகளை உருவகப்படுத்து"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"ஷேட் காட்சியின் நிலை"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"ஆப்ஸ்"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"செயல்பாடுகளை வைத்திருக்காதே"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"பயனர் வெளியேறியதும் செயல்பாடுகளை நீக்கும்"</string>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index fd125b2..c18d771 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"పరికర డిస్‌ప్లేలో మాత్రమే (ఆటోమేటిక్ సెట్టింగ్)"</item>
+    <item msgid="9161645858025071955">"ఎక్స్‌టర్నల్ డిస్‌ప్లే"</item>
+    <item msgid="114384731934682483">"ఫోకస్-ఆధారిత"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"షేడ్‌ను పరికర డిస్‌ప్లేలో మాత్రమే చూపండి"</item>
+    <item msgid="7795034287069726554">"పరికరాన్ని ఒక ఎక్స్‌టర్నల్ డిస్‌ప్లేలో మాత్రమే చూపండి"</item>
+    <item msgid="5280431949814340475">"పరికరాన్ని ఫోకస్ చేసిన చివరి డిస్‌ప్లేలో మాత్రమే చూపండి"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index d6683bb..abee836 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"యాక్టివ్‌గా ఉంది (ఎడమ వైపు మాత్రమే)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"యాక్టివ్‌గా ఉంది (కుడి వైపు మాత్రమే)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"యాక్టివ్‌గా ఉంది (ఎడమ వైపు, కుడి వైపు)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"యాక్టివ్ (మీడియా మాత్రమే). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> బ్యాటరీ."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"యాక్టివ్ (మీడియా మాత్రమే). ఎడమ వైపు: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> బ్యాటరీ, కుడివైపు: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> బ్యాటరీ."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"కనెక్ట్ చేయబడింది (ఆడియో షేరింగ్‌కు సపోర్ట్ చేస్తుంది). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> బ్యాటరీ."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ట్రాన్సిషన్ యానిమేషన్ స్కేల్"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"యానిమేటర్ వ్యవధి స్కేల్"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"ఇతర డిస్‌ప్లేలను సిమ్యులేట్‌ చేయండి"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"షేడ్ డిస్‌ప్లే స్థానం"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"యాప్‌లు"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"యాక్టివిటీస్‌ను ఉంచవద్దు"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"యూజర్ నిష్క్రమించాక పూర్తి యాక్టివిటీని తొలగించండి"</string>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index bf73a22..11cb2ec 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"จอแสดงผลของอุปกรณ์เท่านั้น (ค่าเริ่มต้น)"</item>
+    <item msgid="9161645858025071955">"จอแสดงผลภายนอก"</item>
+    <item msgid="114384731934682483">"Focus-based"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"แสดงเฉดสีในจอแสดงผลของอุปกรณ์เท่านั้น"</item>
+    <item msgid="7795034287069726554">"แสดงอุปกรณ์ในจอแสดงผลภายนอกเครื่องเดียว"</item>
+    <item msgid="5280431949814340475">"แสดงอุปกรณ์ในจอแสดงผลที่โฟกัสล่าสุด"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 6095c50..f8f6af2 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"ใช้งานอยู่ (เฉพาะข้างซ้าย)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"ใช้งานอยู่ (เฉพาะข้างขวา)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"ใช้งานอยู่ (ข้างซ้ายและขวา)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"ใช้งานอยู่ (สื่อเท่านั้น) แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"ใช้งานอยู่ (สื่อเท่านั้น) แบตเตอรี่ข้างซ้าย: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, ข้างขวา: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"เชื่อมต่อแล้ว (รองรับการแชร์เสียง) แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"อัตราการเคลื่อนไหวของการเปลี่ยนภาพ"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"อัตราความเร็วตามตัวสร้างภาพเคลื่อนไหว"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"จำลองจอแสดงผลรอง"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"ตำแหน่งการแสดงผลของเฉดสี"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"แอปพลิเคชัน"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"ไม่เก็บกิจกรรม"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"ล้างทุกกิจกรรมทันทีที่ผู้ใช้ออกไป"</string>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index 94436aa..eae269c 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Display ng device lang (Default)"</item>
+    <item msgid="9161645858025071955">"External na display"</item>
+    <item msgid="114384731934682483">"Focus-based"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Ipakita ang shade sa display ng device lang"</item>
+    <item msgid="7795034287069726554">"Ipakita ang device sa isang external na display"</item>
+    <item msgid="5280431949814340475">"Ipakita ang device sa huling na-focus na display"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 4eb5c1e..8536219 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Aktibo (kaliwa lang)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Aktibo (kanan lang)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Aktibo (kaliwa at kanan)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Aktibo (media lang). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterya."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Aktibo (media lang). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> baterya."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Nakakonekta (sinusuportahan ang pag-share ng audio), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> baterya."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Scale ng transition animation"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Scale ng tagal ng animator"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"I-simulate, ika-2 display"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Posisyon ng display ng shade"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Mga App"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Huwag magtago ng mga aktibidad"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Burahin ang aktibidad kapag iniwan na ito ng user"</string>
diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml
index 27591be..fdb9d21 100644
--- a/packages/SettingsLib/res/values-tr/arrays.xml
+++ b/packages/SettingsLib/res/values-tr/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Yalnızca cihaz ekranı (Varsayılan)"</item>
+    <item msgid="9161645858025071955">"Harici ekran"</item>
+    <item msgid="114384731934682483">"Odaklanmaya dayalı"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Gölgeyi yalnızca cihaz ekranında göster"</item>
+    <item msgid="7795034287069726554">"Cihazı tek bir harici ekranda göster"</item>
+    <item msgid="5280431949814340475">"Cihazı son odaklanılan ekranda göster"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 705b714..8168d53 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Etkin (yalnızca sol taraf)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Etkin (yalnızca sağ taraf)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Etkin (sol ve sağ taraf)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Etkin (yalnızca medya). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pil seviyesi."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Etkin (yalnızca medya). Sol: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, Sağ: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> pil seviyesi."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Bağlı (ses paylaşımını destekler). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pil seviyesi."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Geçiş animasyonu ölçeği"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatör süre ölçeği"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"İkincil ekranları simüle et"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Gölge ekran konumu"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Uygulamalar"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Etkinlikleri saklama"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Kullanıcının ayrıldığı her etkinliği hemen yok et"</string>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index 234af36..2949471 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Лише екран пристрою (за умовчанням)"</item>
+    <item msgid="9161645858025071955">"Зовнішній дисплей"</item>
+    <item msgid="114384731934682483">"На основі фокусування"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Показувати панель лише на екрані пристрою"</item>
+    <item msgid="7795034287069726554">"Показувати панель на одному зовнішньому дисплеї"</item>
+    <item msgid="5280431949814340475">"Показувати панель на останньому активному дисплеї"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index dda905e..3167290 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Активовано (лише лівий)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Активовано (лише правий)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Активовано (лівий і правий)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Активне з’єднання (лише для мультимедіа). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> заряду акумулятора."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Активне з’єднання (лише для мультимедіа). Рівень заряду: лівий <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, правий: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Підключено (підтримує надсилання аудіо). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> заряду акумулятора."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Анімація переходів"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Тривалість анімації"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Імітувати додаткові екрани"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Місце відображення панелі"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Додатки"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Не зберігати дії"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Видаляти зведення дій після їх завершення"</string>
diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml
index df0e56e..a9eadb8 100644
--- a/packages/SettingsLib/res/values-ur/arrays.xml
+++ b/packages/SettingsLib/res/values-ur/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"صرف آلے کا ڈسپلے (ڈیفالٹ)"</item>
+    <item msgid="9161645858025071955">"بیرونی ڈسپلے"</item>
+    <item msgid="114384731934682483">"فوکس پر مبنی"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"صرف آلے کے ڈسپلے پر شیڈ دکھائیں"</item>
+    <item msgid="7795034287069726554">"آلے کو واحد بیرونی ڈسپلے پر دکھائیں"</item>
+    <item msgid="5280431949814340475">"آلے کو آخری فوکس کردہ ڈسپلے پر دکھائیں"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 204663d..fe3dc05 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"فعال ہے (صرف بایاں)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"فعال ہے (صرف دایاں)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"فعال ہے (بایاں اور دایاں)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"فعال (صرف میڈیا)۔ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری۔"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"‏فعال (صرف میڈیا)۔ L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>، ‏R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> بیٹری۔"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"‏منسلک ہے (آڈیو کے اشتراک کو سپورٹ کرتا ہے)۔ ‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> بیٹری۔"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ٹرانزیشن اینیمیشن اسکیل"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"اینیمیٹر دورانیے کا اسکیل"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"ثانوی ڈسپلیز کو تحریک دیں"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"شیڈ ڈسپلے کی پوزیشن"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"ایپس"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"سرگرمیوں کو نہ رکھیں"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"صارف کی ہر سرگرمی صارف کے چھوڑنے پر حذف کر دیں"</string>
diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml
index 3c96530..f3cae41 100644
--- a/packages/SettingsLib/res/values-uz/arrays.xml
+++ b/packages/SettingsLib/res/values-uz/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Faqat qurilma displeyi (birlamchi)"</item>
+    <item msgid="9161645858025071955">"Tashqi displey"</item>
+    <item msgid="114384731934682483">"Fokusga asoslangan"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Faqat qurilma displeyida soyani koʻrsatish"</item>
+    <item msgid="7795034287069726554">"Qurilmani alohida tashqi displeyda koʻrsatish"</item>
+    <item msgid="5280431949814340475">"Qurilmani oxirgi fokuslangan displeyda koʻrsatish"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index a7500a3..d046eff 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Faol (faqat chap)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Faol (faqat oʻng)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Faol (chap va oʻng)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Faol (faqat media uchun) Quvvat: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Faol (faqat media uchun), quvvat: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> (L), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> (R)"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Ulangan (audio yuborish mumkin), quvvat: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"O‘tish animatsiyasi"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatsiya tezligi"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Qo‘shimcha ekran simulyatsiyasi"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Soya displeyi holati"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Ilovalar"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Faollik ma’lumoti saqlanmasin"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Amal tugagach, uning tarixi tozalansin"</string>
diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml
index 9f7768c..e0ebc9f 100644
--- a/packages/SettingsLib/res/values-vi/arrays.xml
+++ b/packages/SettingsLib/res/values-vi/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Chỉ hiển thị trên thiết bị (Mặc định)"</item>
+    <item msgid="9161645858025071955">"Màn hình ngoài"</item>
+    <item msgid="114384731934682483">"Theo tiêu điểm"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Chỉ hiện ngăn thông báo trên màn hình thiết bị"</item>
+    <item msgid="7795034287069726554">"Hiện thiết bị trên một màn hình ngoài"</item>
+    <item msgid="5280431949814340475">"Hiện thiết bị trên màn hình được lấy tiêu điểm gần đây nhất"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 5d620e6..b9617f7 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Đang hoạt động (chỉ tai trái)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Đang hoạt động (chỉ tai phải)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Đang hoạt động (cả tai phải và tai trái)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Đang hoạt động (chỉ phát nội dung đa phương tiện). Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pin."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Đang hoạt động (chỉ phát nội dung đa phương tiện). Bên trái: Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> pin. Bên phải: Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> pin."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Đã kết nối (có hỗ trợ tính năng chia sẻ âm thanh). Còn <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> pin."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Tỷ lệ hình động chuyển tiếp"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Tỷ lệ thời lượng của trình tạo hình động"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Mô phỏng màn hình phụ"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Vị trí hiển thị ngăn thông báo"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Ứng dụng"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Không lưu hoạt động"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Xoá mọi hoạt động ngay khi người dùng rời khỏi"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
index 939b4ec..c2147c7 100644
--- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"仅设备显示屏(默认)"</item>
+    <item msgid="9161645858025071955">"外接显示屏"</item>
+    <item msgid="114384731934682483">"基于焦点"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"仅在设备显示屏上显示通知栏"</item>
+    <item msgid="7795034287069726554">"在单个外接显示屏上显示设备"</item>
+    <item msgid="5280431949814340475">"在最近一次获得焦点的显示屏上显示设备"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 87e03dc..905b221 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"使用中(仅左耳助听器)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"使用中(仅右耳助听器)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"使用中(左右耳助听器)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"使用中(仅限媒体)。电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"使用中(仅限媒体)。左侧电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>,右侧电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>。"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"已连接(支持音频分享)。电池电量为 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"过渡动画缩放"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 时长缩放"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"模拟辅助显示设备"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"通知栏显示位置"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"应用"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"不保留 activity"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"用户离开后即销毁每个 activity"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
index 1370263..37d7b29 100644
--- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"只限裝置顯示屏 (預設)"</item>
+    <item msgid="9161645858025071955">"外部顯示屏"</item>
+    <item msgid="114384731934682483">"突顯"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"只在裝置顯示屏上顯示陰影"</item>
+    <item msgid="7795034287069726554">"在單獨外部顯示屏上顯示裝置"</item>
+    <item msgid="5280431949814340475">"在上一次突顯的顯示屏上顯示裝置"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 6a8d6d5..ccac068 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"使用中 (僅左側)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"使用中 (僅右側)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"使用中 (左右兩側)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"啟用 (只限媒體)。<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> 電量。"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"啟用 (只限媒體),左側:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> 電量,右側:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> 電量。"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"已連線 (支援音訊分享功能),<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> 電量。"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"轉場動畫比例"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 片長比例"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"模擬次要顯示器"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"陰影顯示位置"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"應用程式"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"不要保留活動"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"使用者離開活動後隨即銷毀活動"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
index bbddf61..b851f46 100644
--- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"僅裝置螢幕 (預設)"</item>
+    <item msgid="9161645858025071955">"外接螢幕"</item>
+    <item msgid="114384731934682483">"使用中的螢幕"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"只在裝置螢幕顯示通知欄"</item>
+    <item msgid="7795034287069726554">"在單一外接螢幕顯示通知欄"</item>
+    <item msgid="5280431949814340475">"在上一次使用的螢幕顯示通知欄"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"預設螢幕"</item>
+    <item msgid="774789415968826925">"任何外接螢幕"</item>
+    <item msgid="7880769915418638436">"最新觸控狀態列"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index c5eb0bb..3bd3564 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"使用中 (僅左側)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"使用中 (僅右側)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"使用中 (左右兩側)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"已啟用 (僅限媒體)。電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"已啟用 (僅限媒體)。左側電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>,右側電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>。"</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"已連線 (支援音訊分享)。電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>。"</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"轉場動畫比例"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"動畫影片長度比例"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"模擬次要顯示器"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"通知欄顯示位置"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"應用程式"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"不要保留活動"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"使用者離開活動後立刻刪除所有活動內容"</string>
diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml
index c202896..27ca40c 100644
--- a/packages/SettingsLib/res/values-zu/arrays.xml
+++ b/packages/SettingsLib/res/values-zu/arrays.xml
@@ -288,4 +288,19 @@
     <item msgid="3753634915787796632">"2"</item>
     <item msgid="4779928470672877922">"3"</item>
   </string-array>
+  <string-array name="shade_display_awareness_entries">
+    <item msgid="816770658383209617">"Ukuboniswa kwedivayisi kuphela (Okuzenzakalelayo)"</item>
+    <item msgid="9161645858025071955">"Ukubonisa Kwangaphandle"</item>
+    <item msgid="114384731934682483">"Kusekelwe ekugxileni"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_summaries">
+    <item msgid="2964753205732912921">"Bonisa umthunzi esibonisini sedivayisi kuphela"</item>
+    <item msgid="7795034287069726554">"Bonisa idivayisi esibonisini sangaphandle esisodwa"</item>
+    <item msgid="5280431949814340475">"Bonisa idivayisi esibonisini sokugcina esigxilile"</item>
+  </string-array>
+  <string-array name="shade_display_awareness_values">
+    <item msgid="3055776101992426514">"default_display"</item>
+    <item msgid="774789415968826925">"any_external_display"</item>
+    <item msgid="7880769915418638436">"status_bar_latest_touch"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index f467a3a..7d96423 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -110,6 +110,8 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="8330226430756799572">"Iyasebenza (ngakwesokunxele kuphela)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="2244728507170385397">"Iyasebenza (ngakwesokudla kuphela)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="4294571497939983181">"Iyasebenza (ngakwesokunxele nakwesokudla)"</string>
+    <!-- no translation found for bluetooth_hearing_device_ambient_error (6035857289108813878) -->
+    <skip />
     <string name="bluetooth_active_media_only_battery_level" msgid="7772517511061834073">"Iyasebenza (imidiya kuphela). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ibhethri."</string>
     <string name="bluetooth_active_media_only_battery_level_untethered" msgid="7444753133664620926">"Iyasebenza (imidiya kuphela). L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ibhethri."</string>
     <string name="bluetooth_battery_level_lea_support" msgid="5968584103507988820">"Ixhunyiwe (isekela ukwabelana ngokuqoshiwe). <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ibhethri."</string>
@@ -423,6 +425,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Isilinganiso sesithombe soku"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Isilinganiso sobude besikhathi somenzi womfanekiso onyakazayo"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Hlalisa kahle ukubukwa kwesibili"</string>
+    <string name="shade_display_awareness_title" msgid="8000009404669495876">"Indawo yokubonisa umthunzi"</string>
     <string name="debug_applications_category" msgid="5394089406638954196">"Izinhlelo zokusebenza"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ungagcini imisibenzi"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Phihliza zonke izenzo ngokushesha ngemva kokuna umsebenzisi awuyeka"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index b4afb7d..7374f80 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -444,12 +444,23 @@
     }
 
     /**
-     * @return {@code true} if {@code cachedBluetoothDevice} is hearing aid device
+     * @return {@code true} if {@code cachedBluetoothDevice} is hearing aid device.
+     * @deprecated use {@link #isHearingDevice() }
+     * // TODO: b/385679160 - Target to deprecate it and replace  with #isHearingDevice()
      */
+    @Deprecated
     public boolean isHearingAidDevice() {
         return mHearingAidInfo != null;
     }
 
+    /**
+     * @return {@code true} if {@code cachedBluetoothDevice} support any of hearing device profile.
+     */
+    public boolean isHearingDevice() {
+        return getProfiles().stream().anyMatch(
+                p -> (p instanceof HearingAidProfile || p instanceof HapClientProfile));
+    }
+
     public int getDeviceSide() {
         return mHearingAidInfo != null
                 ? mHearingAidInfo.getSide() : HearingAidInfo.DeviceSide.SIDE_INVALID;
@@ -910,12 +921,33 @@
         }
     }
 
+    /**
+     * Checks if the device is connected to the specified Bluetooth profile.
+     *
+     * @param profile The Bluetooth profile to check.
+     * @return {@code true} if the device is connected to the profile.
+     */
     public boolean isConnectedProfile(LocalBluetoothProfile profile) {
         int status = getProfileConnectionState(profile);
         return status == BluetoothProfile.STATE_CONNECTED;
 
     }
 
+    /**
+     * Checks if the device is connected to the Bluetooth profile with the given ID.
+     *
+     * @param profileId The ID of the Bluetooth profile to check.
+     * @return {@code true} if the device is connected to the profile.
+     */
+    public boolean isConnectedProfile(int profileId) {
+        for (LocalBluetoothProfile profile : getProfiles()) {
+            if (profile.getProfileId() == profileId) {
+                return isConnectedProfile(profile);
+            }
+        }
+        return false;
+    }
+
     public boolean isBusy() {
         synchronized (mProfileLock) {
             for (LocalBluetoothProfile profile : mProfiles) {
@@ -1891,13 +1923,6 @@
     }
 
     /**
-     * @return {@code true} if {@code cachedBluetoothDevice} is LeAudio hearing aid device
-     */
-    public boolean isConnectedLeAudioHearingAidDevice() {
-        return isConnectedHapClientDevice() && isConnectedLeAudioDevice();
-    }
-
-    /**
      * @return {@code true} if {@code cachedBluetoothDevice} is hearing aid device
      *
      * The device may be an ASHA hearing aid that supports {@link HearingAidProfile} or a LeAudio
@@ -1908,6 +1933,13 @@
     }
 
     /**
+     * @return {@code true} if {@code cachedBluetoothDevice} is LeAudio hearing aid device
+     */
+    public boolean isConnectedLeAudioHearingAidDevice() {
+        return isConnectedHapClientDevice() && isConnectedLeAudioDevice();
+    }
+
+    /**
      * @return {@code true} if {@code cachedBluetoothDevice} is LeAudio device
      */
     public boolean isConnectedLeAudioDevice() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index b754706..313013c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -24,7 +24,10 @@
 import android.content.Context;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.settingslib.flags.Flags;
 
 import java.sql.Timestamp;
 import java.util.ArrayList;
@@ -46,7 +49,7 @@
     private final LocalBluetoothManager mBtManager;
 
     @VisibleForTesting
-    final List<CachedBluetoothDevice> mCachedDevices = new ArrayList<CachedBluetoothDevice>();
+    final List<CachedBluetoothDevice> mCachedDevices = new ArrayList<>();
     @VisibleForTesting
     HearingAidDeviceManager mHearingAidDeviceManager;
     @VisibleForTesting
@@ -192,6 +195,20 @@
     }
 
     /**
+     * Notifies the connection status if device is hearing device.
+     *
+     * @param device The {@link CachedBluetoothDevice} need to be hearing device
+     */
+    public synchronized void notifyHearingDevicesConnectionStatusChangedIfNeeded(
+            @NonNull CachedBluetoothDevice device) {
+        if (!device.isHearingDevice()) {
+            return;
+        }
+
+        mHearingAidDeviceManager.notifyDevicesConnectionStatusChanged();
+    }
+
+    /**
      * Search for existing sub device {@link CachedBluetoothDevice}.
      *
      * @param device the address of the Bluetooth device
@@ -388,8 +405,14 @@
 
     /** Handles when the device been set as active/inactive. */
     public synchronized void onActiveDeviceChanged(CachedBluetoothDevice cachedBluetoothDevice) {
-        if (cachedBluetoothDevice.isHearingAidDevice()) {
+        if (cachedBluetoothDevice == null) {
+            return;
+        }
+        if (cachedBluetoothDevice.isHearingDevice()) {
             mHearingAidDeviceManager.onActiveDeviceChanged(cachedBluetoothDevice);
+            if (Flags.hearingDeviceSetConnectionStatusReport()) {
+                mHearingAidDeviceManager.notifyDevicesConnectionStatusChanged();
+            }
         }
     }
 
@@ -421,6 +444,14 @@
             mainDevice.unpair();
             mainDevice.setSubDevice(null);
         }
+
+        // TODO: b/386121967 - Should change to use isHearingDevice but mProfile get clear here.
+        //  Need to consider where to put this logic when using isHearingDevice()
+        if (device.isHearingAidDevice()) {
+            if (Flags.hearingDeviceSetConnectionStatusReport()) {
+                mHearingAidDeviceManager.notifyDevicesConnectionStatusChanged();
+            }
+        }
     }
 
     /**
@@ -579,6 +610,11 @@
         return mOngoingSetMemberPair != null && mOngoingSetMemberPair.equals(device);
     }
 
+    @NonNull
+    public HearingAidDeviceManager getHearingAidDeviceManager() {
+        return mHearingAidDeviceManager;
+    }
+
     private void log(String msg) {
         if (DEBUG) {
             Log.d(TAG, msg);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingConstants.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingConstants.java
index ca0cad7..7d91050 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingConstants.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingConstants.java
@@ -19,6 +19,7 @@
 import android.media.AudioAttributes;
 import android.media.AudioDeviceAttributes;
 import android.media.AudioDeviceInfo;
+import android.media.MediaRecorder;
 
 import androidx.annotation.IntDef;
 
@@ -61,15 +62,20 @@
     @IntDef({
             RoutingValue.AUTO,
             RoutingValue.HEARING_DEVICE,
-            RoutingValue.DEVICE_SPEAKER,
+            RoutingValue.BUILTIN_DEVICE,
     })
 
     public @interface RoutingValue {
         int AUTO = 0;
         int HEARING_DEVICE = 1;
-        int DEVICE_SPEAKER = 2;
+        int BUILTIN_DEVICE = 2;
     }
 
-    public static final AudioDeviceAttributes DEVICE_SPEAKER_OUT = new AudioDeviceAttributes(
+    public static final AudioDeviceAttributes BUILTIN_SPEAKER = new AudioDeviceAttributes(
             AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, "");
+    public static final AudioDeviceAttributes BUILTIN_MIC = new AudioDeviceAttributes(
+            AudioDeviceAttributes.ROLE_INPUT, AudioDeviceInfo.TYPE_BUILTIN_MIC, "");
+
+    public static final int MICROPHONE_SOURCE_VOICE_COMMUNICATION =
+            MediaRecorder.AudioSource.VOICE_COMMUNICATION;
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelper.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelper.java
index 8eaea0e..1f72725 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelper.java
@@ -16,26 +16,34 @@
 
 package com.android.settingslib.bluetooth;
 
+import static com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants.BUILTIN_MIC;
+import static com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants.MICROPHONE_SOURCE_VOICE_COMMUNICATION;
+
 import android.content.Context;
 import android.media.AudioAttributes;
 import android.media.AudioDeviceAttributes;
 import android.media.AudioDeviceInfo;
 import android.media.AudioManager;
 import android.media.audiopolicy.AudioProductStrategy;
+import android.util.Log;
 
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants.RoutingValue;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
- * A helper class to configure the routing strategy for hearing aids.
+ * A helper class to configure the audio routing for hearing aids.
  */
 public class HearingAidAudioRoutingHelper {
 
+    private static final String TAG = "HearingAidAudioRoutingHelper";
+
     private final AudioManager mAudioManager;
 
     public HearingAidAudioRoutingHelper(Context context) {
@@ -73,26 +81,26 @@
      * @param hearingDevice {@link AudioDeviceAttributes} of the device to be changed in audio
      *                      routing
      * @param routingValue one of value defined in
-     *                     {@link HearingAidAudioRoutingConstants.RoutingValue}, denotes routing
+     *                     {@link RoutingValue}, denotes routing
      *                     destination.
      * @return {code true} if the routing value successfully configure
      */
     public boolean setPreferredDeviceRoutingStrategies(
             List<AudioProductStrategy> supportedStrategies, AudioDeviceAttributes hearingDevice,
-            @HearingAidAudioRoutingConstants.RoutingValue int routingValue) {
+            @RoutingValue int routingValue) {
         boolean status;
         switch (routingValue) {
-            case HearingAidAudioRoutingConstants.RoutingValue.AUTO:
+            case RoutingValue.AUTO:
                 status = removePreferredDeviceForStrategies(supportedStrategies);
                 return status;
-            case HearingAidAudioRoutingConstants.RoutingValue.HEARING_DEVICE:
+            case RoutingValue.HEARING_DEVICE:
                 status = removePreferredDeviceForStrategies(supportedStrategies);
                 status &= setPreferredDeviceForStrategies(supportedStrategies, hearingDevice);
                 return status;
-            case HearingAidAudioRoutingConstants.RoutingValue.DEVICE_SPEAKER:
+            case RoutingValue.BUILTIN_DEVICE:
                 status = removePreferredDeviceForStrategies(supportedStrategies);
                 status &= setPreferredDeviceForStrategies(supportedStrategies,
-                        HearingAidAudioRoutingConstants.DEVICE_SPEAKER_OUT);
+                        HearingAidAudioRoutingConstants.BUILTIN_SPEAKER);
                 return status;
             default:
                 throw new IllegalArgumentException("Unexpected routingValue: " + routingValue);
@@ -100,21 +108,76 @@
     }
 
     /**
-     * Gets the matched hearing device {@link AudioDeviceAttributes} for {@code device}.
+     * Set the preferred input device for calls.
      *
-     * <p>Will also try to match the {@link CachedBluetoothDevice#getSubDevice()} of {@code device}
+     * <p>Note that hearing device needs to be valid input device to be found in AudioManager.
+     * <p>Routing value can be:
+     * <ul>
+     *     <li> {@link RoutingValue#AUTO} - Allow the system to automatically select the appropriate
+     *     audio routing for calls.</li>
+     *     <li> {@link RoutingValue#HEARING_DEVICE} - Set input device to this hearing device.</li>
+     *     <li> {@link RoutingValue#BUILTIN_DEVICE} - Set input device to builtin microphone. </li>
+     * </ul>
+     * @param routingValue The desired routing value for calls
+     * @return {@code true} if the operation was successful
+     */
+    public boolean setPreferredInputDeviceForCalls(@Nullable CachedBluetoothDevice hearingDevice,
+            @RoutingValue int routingValue) {
+        AudioDeviceAttributes hearingDeviceAttributes = getMatchedHearingDeviceAttributesInput(
+                hearingDevice);
+        if (hearingDeviceAttributes == null) {
+            Log.w(TAG, "Can not find expected input AudioDeviceAttributes for hearing device: "
+                    + hearingDevice.getDevice().getAnonymizedAddress());
+            return false;
+        }
+
+        final int audioSource = MICROPHONE_SOURCE_VOICE_COMMUNICATION;
+        return switch (routingValue) {
+            case RoutingValue.AUTO ->
+                    mAudioManager.clearPreferredDevicesForCapturePreset(audioSource);
+            case RoutingValue.HEARING_DEVICE -> {
+                mAudioManager.clearPreferredDevicesForCapturePreset(audioSource);
+                yield mAudioManager.setPreferredDeviceForCapturePreset(audioSource,
+                        hearingDeviceAttributes);
+            }
+            case RoutingValue.BUILTIN_DEVICE -> {
+                mAudioManager.clearPreferredDevicesForCapturePreset(audioSource);
+                yield mAudioManager.setPreferredDeviceForCapturePreset(audioSource, BUILTIN_MIC);
+            }
+            default -> throw new IllegalArgumentException(
+                    "Unexpected routingValue: " + routingValue);
+        };
+    }
+
+    /**
+     * Clears the preferred input device for calls.
+     *
+     * {@code true} if the operation was successful
+     */
+    public boolean clearPreferredInputDeviceForCalls() {
+        return mAudioManager.clearPreferredDevicesForCapturePreset(
+                MICROPHONE_SOURCE_VOICE_COMMUNICATION);
+    }
+
+    /**
+     * Gets the matched output hearing device {@link AudioDeviceAttributes} for {@code device}.
+     *
+     * <p>Will also try to match the {@link CachedBluetoothDevice#getSubDevice()} and
+     * {@link CachedBluetoothDevice#getMemberDevice()} of {@code device}
      *
      * @param device the {@link CachedBluetoothDevice} need to be hearing aid device
      * @return the requested AudioDeviceAttributes or {@code null} if not match
      */
     @Nullable
-    public AudioDeviceAttributes getMatchedHearingDeviceAttributes(CachedBluetoothDevice device) {
+    public AudioDeviceAttributes getMatchedHearingDeviceAttributesForOutput(
+            @Nullable CachedBluetoothDevice device) {
         if (device == null || !device.isHearingAidDevice()) {
             return null;
         }
 
         AudioDeviceInfo[] audioDevices = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
         for (AudioDeviceInfo audioDevice : audioDevices) {
+            //TODO: b/370812132 - Need to update if TYPE_LEA_HEARING_AID is added
             // ASHA for TYPE_HEARING_AID, HAP for TYPE_BLE_HEADSET
             if (audioDevice.getType() == AudioDeviceInfo.TYPE_HEARING_AID
                     || audioDevice.getType() == AudioDeviceInfo.TYPE_BLE_HEADSET) {
@@ -126,6 +189,35 @@
         return null;
     }
 
+    /**
+     * Gets the matched input hearing device {@link AudioDeviceAttributes} for {@code device}.
+     *
+     * <p>Will also try to match the {@link CachedBluetoothDevice#getSubDevice()} and
+     * {@link CachedBluetoothDevice#getMemberDevice()} of {@code device}
+     *
+     * @param device the {@link CachedBluetoothDevice} need to be hearing aid device
+     * @return the requested AudioDeviceAttributes or {@code null} if not match
+     */
+    @Nullable
+    private AudioDeviceAttributes getMatchedHearingDeviceAttributesInput(
+            @Nullable CachedBluetoothDevice device) {
+        if (device == null || !device.isHearingAidDevice()) {
+            return null;
+        }
+
+        AudioDeviceInfo[] audioDevices = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
+        for (AudioDeviceInfo audioDevice : audioDevices) {
+            //TODO: b/370812132 - Need to update if TYPE_LEA_HEARING_AID is added
+            // HAP for TYPE_BLE_HEADSET
+            if (audioDevice.getType() == AudioDeviceInfo.TYPE_BLE_HEADSET) {
+                if (matchAddress(device, audioDevice)) {
+                    return new AudioDeviceAttributes(audioDevice);
+                }
+            }
+        }
+        return null;
+    }
+
     private boolean matchAddress(CachedBluetoothDevice device, AudioDeviceInfo audioDevice) {
         final String audioDeviceAddress = audioDevice.getAddress();
         final CachedBluetoothDevice subDevice = device.getSubDevice();
@@ -142,7 +234,6 @@
         boolean status = true;
         for (AudioProductStrategy strategy : strategies) {
             status &= mAudioManager.setPreferredDeviceForStrategy(strategy, audioDevice);
-
         }
 
         return status;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
index 1ca4c2b..b2c2794 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
@@ -15,7 +15,11 @@
  */
 package com.android.settingslib.bluetooth;
 
+import static android.bluetooth.BluetoothDevice.BOND_BONDED;
+
+import android.annotation.CallbackExecutor;
 import android.bluetooth.BluetoothCsipSetCoordinator;
+import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHapClient;
 import android.bluetooth.BluetoothHearingAid;
 import android.bluetooth.BluetoothProfile;
@@ -30,14 +34,25 @@
 import android.util.FeatureFlagUtils;
 import android.util.Log;
 
-import com.android.internal.annotations.VisibleForTesting;
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.collection.ArraySet;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants.RoutingValue;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+import java.util.stream.Collectors;
 
 /**
- * HearingAidDeviceManager manages the set of remote HearingAid(ASHA) Bluetooth devices.
+ * HearingAidDeviceManager manages the set of remote bluetooth hearing devices.
  */
 public class HearingAidDeviceManager {
     private static final String TAG = "HearingAidDeviceManager";
@@ -48,6 +63,12 @@
     private final LocalBluetoothManager mBtManager;
     private final List<CachedBluetoothDevice> mCachedDevices;
     private final HearingAidAudioRoutingHelper mRoutingHelper;
+    private static final Map<ConnectionStatusListener, Executor>
+            mConnectionStatusListeners = new ConcurrentHashMap<>();
+    @ConnectionStatus
+    private int mDevicesConnectionStatus = ConnectionStatus.NO_DEVICE_BONDED;
+    private boolean mInitialDevicesConnectionStatusUpdate = false;
+
     HearingAidDeviceManager(Context context, LocalBluetoothManager localBtManager,
             List<CachedBluetoothDevice> CachedDevices) {
         mContext = context;
@@ -67,6 +88,191 @@
         mRoutingHelper = routingHelper;
     }
 
+    /**
+     * Defines the connection status for hearing devices.
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            ConnectionStatus.NO_DEVICE_BONDED,
+            ConnectionStatus.DISCONNECTED,
+            ConnectionStatus.CONNECTED,
+            ConnectionStatus.CONNECTING_OR_DISCONNECTING,
+            ConnectionStatus.ACTIVE
+    })
+    public @interface ConnectionStatus {
+        int NO_DEVICE_BONDED = -1;
+        int DISCONNECTED = 0;
+        int CONNECTED = 1;
+        int CONNECTING_OR_DISCONNECTING = 2;
+        int ACTIVE = 3;
+    }
+    /**
+     * Interface for connection status listener.
+     */
+    public interface ConnectionStatusListener {
+        /**
+         * Callback when hearing devices connection status change.
+         *
+         * <p>devices here means singular device or binaural device.
+         * E.g. One of hearing device is in CONNECTED status and another is in DISCONNECTED,
+         * it will callback CONNECTED status.
+         *
+         * @param status Updated {@link ConnectionStatus}
+         */
+        void onDevicesConnectionStatusChanged(@ConnectionStatus int status);
+    }
+
+    /**
+     * Registers a listener to be notified of connection status changes.
+     *
+     * @param listener The listener to register.
+     * @param executor The executor on which the listener's callback will be run.
+     */
+    public void registerConnectionStatusListener(
+            @NonNull ConnectionStatusListener listener,
+            @NonNull @CallbackExecutor Executor executor) {
+        mConnectionStatusListeners.put(listener, executor);
+    }
+
+    /**
+     * Unregisters a listener previously registered with
+     * {@link #registerConnectionStatusListener(ConnectionStatusListener, Executor)}.
+     *
+     * @param listener The listener to unregister.
+     */
+    public void unregisterConnectionStatusListener(
+            @NonNull ConnectionStatusListener listener) {
+        mConnectionStatusListeners.remove(listener);
+    }
+
+    private void notifyDevicesConnectionStatusChanged(int status) {
+        mConnectionStatusListeners.forEach((listener, executor) ->
+                executor.execute(() -> listener.onDevicesConnectionStatusChanged(status)));
+    }
+
+    /**
+     * Updates the connection status of the hearing devices based on the currently bonded
+     * hearing aid devices.
+     */
+    synchronized void notifyDevicesConnectionStatusChanged() {
+        final int prevVal = mDevicesConnectionStatus;
+        updateDevicesConnectionStatus();
+        if (mDevicesConnectionStatus != prevVal) {
+            notifyDevicesConnectionStatusChanged(mDevicesConnectionStatus);
+        }
+    }
+
+    private void updateDevicesConnectionStatus() {
+        mInitialDevicesConnectionStatusUpdate = true;
+        // Add all hearing devices including sub and member into a set.
+        Set<CachedBluetoothDevice> allHearingDevices = mCachedDevices.stream()
+                .filter(d -> d.getBondState() == BluetoothDevice.BOND_BONDED
+                        && d.isHearingDevice())
+                .flatMap(d -> getAssociatedCachedDevice(d).stream())
+                .collect(Collectors.toSet());
+
+        // Status sequence matters here. If one of the hearing devices is in previous
+        // ConnectionStatus, we will treat whole hearing devices is in this status.
+        // E.g. One of hearing device is in CONNECTED status and another is in DISCONNECTED
+        // status, the hearing devices connection status will notify CONNECTED status.
+        if (isConnectingOrDisconnectingConnectionStatus(allHearingDevices)) {
+            mDevicesConnectionStatus = ConnectionStatus.CONNECTING_OR_DISCONNECTING;
+        } else if (isActiveConnectionStatus(allHearingDevices)) {
+            mDevicesConnectionStatus = ConnectionStatus.ACTIVE;
+        } else if (isConnectedStatus(allHearingDevices)) {
+            mDevicesConnectionStatus = ConnectionStatus.CONNECTED;
+        } else if (isDisconnectedStatus(allHearingDevices)) {
+            mDevicesConnectionStatus = ConnectionStatus.DISCONNECTED;
+        } else {
+            mDevicesConnectionStatus = ConnectionStatus.NO_DEVICE_BONDED;
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "updateDevicesConnectionStatus: " + mDevicesConnectionStatus);
+        }
+    }
+
+    /**
+     * @return all the related CachedBluetoothDevices for this device.
+     */
+    @NonNull
+    public Set<CachedBluetoothDevice> getAssociatedCachedDevice(
+            @NonNull CachedBluetoothDevice device) {
+        ArraySet<CachedBluetoothDevice> cachedDeviceSet = new ArraySet<>();
+        cachedDeviceSet.add(device);
+        // Associated device should be added into memberDevice if it support CSIP profile.
+        Set<CachedBluetoothDevice> memberDevices = device.getMemberDevice();
+        if (!memberDevices.isEmpty()) {
+            cachedDeviceSet.addAll(memberDevices);
+            return cachedDeviceSet;
+        }
+        // If not support CSIP profile, it should be ASHA hearing device and added into subDevice.
+        CachedBluetoothDevice subDevice = device.getSubDevice();
+        if (subDevice != null) {
+            cachedDeviceSet.add(subDevice);
+            return cachedDeviceSet;
+        }
+
+        return cachedDeviceSet;
+    }
+
+    private boolean isConnectingOrDisconnectingConnectionStatus(
+            Set<CachedBluetoothDevice> devices) {
+        HearingAidProfile hearingAidProfile = mBtManager.getProfileManager().getHearingAidProfile();
+        HapClientProfile hapClientProfile = mBtManager.getProfileManager().getHapClientProfile();
+
+        for (CachedBluetoothDevice device : devices) {
+            if (hearingAidProfile != null) {
+                int status = device.getProfileConnectionState(hearingAidProfile);
+                if (status == BluetoothProfile.STATE_DISCONNECTING
+                        || status == BluetoothProfile.STATE_CONNECTING) {
+                    return true;
+                }
+            }
+            if (hapClientProfile != null) {
+                int status = device.getProfileConnectionState(hapClientProfile);
+                if (status == BluetoothProfile.STATE_DISCONNECTING
+                        || status == BluetoothProfile.STATE_CONNECTING) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean isActiveConnectionStatus(Set<CachedBluetoothDevice> devices) {
+        for (CachedBluetoothDevice device : devices) {
+            if ((device.isActiveDevice(BluetoothProfile.HEARING_AID)
+                    && device.isConnectedProfile(BluetoothProfile.HEARING_AID))
+                    || (device.isActiveDevice(BluetoothProfile.LE_AUDIO)
+                    && device.isConnectedProfile(BluetoothProfile.LE_AUDIO))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isConnectedStatus(Set<CachedBluetoothDevice> devices) {
+        return devices.stream().anyMatch(CachedBluetoothDevice::isConnected);
+    }
+
+    private boolean isDisconnectedStatus(Set<CachedBluetoothDevice> devices) {
+        return devices.stream().anyMatch(
+                d -> (!d.isConnected() && d.getBondState() == BOND_BONDED));
+    }
+
+    /**
+     * Gets the connection status for hearing device set. Will update connection status first if
+     * never updated.
+     */
+    @ConnectionStatus
+    public int getDevicesConnectionStatus() {
+        if (!mInitialDevicesConnectionStatusUpdate) {
+            updateDevicesConnectionStatus();
+        }
+        return mDevicesConnectionStatus;
+    }
+
     void initHearingAidDeviceIfNeeded(CachedBluetoothDevice newDevice,
             List<ScanFilter> leScanFilters) {
         HearingAidInfo info = generateHearingAidInfo(newDevice);
@@ -277,13 +483,19 @@
 
     void onActiveDeviceChanged(CachedBluetoothDevice device) {
         if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_AUDIO_ROUTING)) {
-            if (device.isActiveDevice(BluetoothProfile.HEARING_AID) || device.isActiveDevice(
-                    BluetoothProfile.LE_AUDIO)) {
+            if (device.isConnectedHearingAidDevice()) {
                 setAudioRoutingConfig(device);
             } else {
                 clearAudioRoutingConfig();
             }
         }
+        if (com.android.settingslib.flags.Flags.hearingDevicesInputRoutingControl()) {
+            if (device.isConnectedHearingAidDevice()) {
+                setMicrophoneForCalls(device);
+            } else {
+                clearMicrophoneForCalls();
+            }
+        }
     }
 
     void syncDeviceIfNeeded(CachedBluetoothDevice device) {
@@ -311,9 +523,25 @@
         HearingDeviceLocalDataManager.clear(mContext, device.getDevice());
     }
 
+    private void setMicrophoneForCalls(CachedBluetoothDevice device) {
+        boolean useRemoteMicrophone = device.getDevice().isMicrophonePreferredForCalls();
+        boolean status = mRoutingHelper.setPreferredInputDeviceForCalls(device,
+                useRemoteMicrophone ? RoutingValue.AUTO : RoutingValue.BUILTIN_DEVICE);
+        if (!status) {
+            Log.d(TAG, "Fail to configure setPreferredInputDeviceForCalls");
+        }
+    }
+
+    private void clearMicrophoneForCalls() {
+        boolean status = mRoutingHelper.clearPreferredInputDeviceForCalls();
+        if (!status) {
+            Log.d(TAG, "Fail to configure clearMicrophoneForCalls");
+        }
+    }
+
     private void setAudioRoutingConfig(CachedBluetoothDevice device) {
         AudioDeviceAttributes hearingDeviceAttributes =
-                mRoutingHelper.getMatchedHearingDeviceAttributes(device);
+                mRoutingHelper.getMatchedHearingDeviceAttributesForOutput(device);
         if (hearingDeviceAttributes == null) {
             Log.w(TAG, "Can not find expected AudioDeviceAttributes for hearing device: "
                     + device.getDevice().getAnonymizedAddress());
@@ -321,17 +549,13 @@
         }
 
         final int callRoutingValue = Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.HEARING_AID_CALL_ROUTING,
-                HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+                Settings.Secure.HEARING_AID_CALL_ROUTING, RoutingValue.AUTO);
         final int mediaRoutingValue = Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.HEARING_AID_MEDIA_ROUTING,
-                HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+                Settings.Secure.HEARING_AID_MEDIA_ROUTING, RoutingValue.AUTO);
         final int ringtoneRoutingValue = Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.HEARING_AID_RINGTONE_ROUTING,
-                HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+                Settings.Secure.HEARING_AID_RINGTONE_ROUTING, RoutingValue.AUTO);
         final int systemSoundsRoutingValue = Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.HEARING_AID_NOTIFICATION_ROUTING,
-                HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+                Settings.Secure.HEARING_AID_NOTIFICATION_ROUTING, RoutingValue.AUTO);
 
         setPreferredDeviceRoutingStrategies(
                 HearingAidAudioRoutingConstants.CALL_ROUTING_ATTRIBUTES,
@@ -351,21 +575,21 @@
         // Don't need to pass hearingDevice when we want to reset it (set to AUTO).
         setPreferredDeviceRoutingStrategies(
                 HearingAidAudioRoutingConstants.CALL_ROUTING_ATTRIBUTES,
-                /* hearingDevice = */ null, HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+                /* hearingDevice = */ null, RoutingValue.AUTO);
         setPreferredDeviceRoutingStrategies(
                 HearingAidAudioRoutingConstants.MEDIA_ROUTING_ATTRIBUTES,
-                /* hearingDevice = */ null, HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+                /* hearingDevice = */ null, RoutingValue.AUTO);
         setPreferredDeviceRoutingStrategies(
                 HearingAidAudioRoutingConstants.RINGTONE_ROUTING_ATTRIBUTES,
-                /* hearingDevice = */ null, HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+                /* hearingDevice = */ null, RoutingValue.AUTO);
         setPreferredDeviceRoutingStrategies(
                 HearingAidAudioRoutingConstants.NOTIFICATION_ROUTING_ATTRIBUTES,
-                /* hearingDevice = */ null, HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+                /* hearingDevice = */ null, RoutingValue.AUTO);
     }
 
     private void setPreferredDeviceRoutingStrategies(int[] attributeSdkUsageList,
             AudioDeviceAttributes hearingDevice,
-            @HearingAidAudioRoutingConstants.RoutingValue int routingValue) {
+            @RoutingValue int routingValue) {
         final List<AudioProductStrategy> supportedStrategies =
                 mRoutingHelper.getSupportedStrategies(attributeSdkUsageList);
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 8dfeb55..7c24df9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -47,12 +47,14 @@
 
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.CollectionUtils;
+import com.android.settingslib.flags.Flags;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 
@@ -345,11 +347,17 @@
                     oldState == BluetoothProfile.STATE_CONNECTING) {
                 Log.i(TAG, "Failed to connect " + mProfile + " device");
             }
+            final boolean isAshaProfile = getHearingAidProfile() != null
+                    && mProfile instanceof HearingAidProfile;
+            final boolean isHapClientProfile = getHapClientProfile() != null
+                    && mProfile instanceof HapClientProfile;
+            final boolean isLeAudioProfile = getLeAudioProfile() != null
+                    && mProfile instanceof LeAudioProfile;
+            final boolean isHapClientOrLeAudioProfile = isHapClientProfile || isLeAudioProfile;
+            final boolean isCsipProfile = getCsipSetCoordinatorProfile() != null
+                    && mProfile instanceof CsipSetCoordinatorProfile;
 
-            if (getHearingAidProfile() != null
-                    && mProfile instanceof HearingAidProfile
-                    && (newState == BluetoothProfile.STATE_CONNECTED)) {
-
+            if (isAshaProfile && (newState == BluetoothProfile.STATE_CONNECTED)) {
                 // Check if the HiSyncID has being initialized
                 if (cachedDevice.getHiSyncId() == BluetoothHearingAid.HI_SYNC_ID_INVALID) {
                     long newHiSyncId = getHearingAidProfile().getHiSyncId(cachedDevice.getDevice());
@@ -366,11 +374,6 @@
                 HearingAidStatsLogUtils.logHearingAidInfo(cachedDevice);
             }
 
-            final boolean isHapClientProfile = getHapClientProfile() != null
-                    && mProfile instanceof HapClientProfile;
-            final boolean isLeAudioProfile = getLeAudioProfile() != null
-                    && mProfile instanceof LeAudioProfile;
-            final boolean isHapClientOrLeAudioProfile = isHapClientProfile || isLeAudioProfile;
             if (isHapClientOrLeAudioProfile && newState == BluetoothProfile.STATE_CONNECTED) {
 
                 // Checks if both profiles are connected to the device. Hearing aid info need
@@ -385,9 +388,7 @@
                 }
             }
 
-            if (getCsipSetCoordinatorProfile() != null
-                    && mProfile instanceof CsipSetCoordinatorProfile
-                    && newState == BluetoothProfile.STATE_CONNECTED) {
+            if (isCsipProfile && (newState == BluetoothProfile.STATE_CONNECTED)) {
                 // Check if the GroupID has being initialized
                 if (cachedDevice.getGroupId() == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
                     final Map<Integer, ParcelUuid> groupIdMap = getCsipSetCoordinatorProfile()
@@ -403,6 +404,21 @@
                 }
             }
 
+            // LE_AUDIO, CSIP_SET_COORDINATOR profiles will also impact the connection status
+            // change, e.g. device need to active on LE_AUDIO to become active connection status.
+            final Set<Integer> hearingDeviceConnectionStatusProfileId = Set.of(
+                    BluetoothProfile.HEARING_AID,
+                    BluetoothProfile.HAP_CLIENT,
+                    BluetoothProfile.LE_AUDIO,
+                    BluetoothProfile.CSIP_SET_COORDINATOR
+            );
+            if (Flags.hearingDeviceSetConnectionStatusReport()) {
+                if (hearingDeviceConnectionStatusProfileId.contains(mProfile.getProfileId())) {
+                    mDeviceManager.notifyHearingDevicesConnectionStatusChangedIfNeeded(
+                            cachedDevice);
+                }
+            }
+
             cachedDevice.onProfileStateChanged(mProfile, newState);
             // Dispatch profile changed after device update
             boolean needDispatchProfileConnectionState = true;
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java
index 714f951..f6acac1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java
@@ -18,8 +18,6 @@
 
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
-import android.telephony.UiccPortInfo;
-import android.telephony.UiccSlotMapping;
 
 public class DataServiceUtils {
 
@@ -43,35 +41,6 @@
          * {@see MobileNetworkUtils#isMobileDataEnabled(Context)}.
          */
         public static final String COLUMN_IS_MOBILE_DATA_ENABLED = "isMobileDataEnabled";
-
-        /**
-         * The name of the show toggle for physicalSim state column,
-         * {@see SubscriptionUtil#showToggleForPhysicalSim(SubscriptionManager)}.
-         */
-        public static final String COLUMN_SHOW_TOGGLE_FOR_PHYSICAL_SIM = "showToggleForPhysicalSim";
-    }
-
-    /**
-     * Represents columns of the UiccInfoData table, define these columns from
-     * {@link android.telephony.UiccSlotInfo}, {@link android.telephony.UiccCardInfo},
-     * {@link UiccSlotMapping} and {@link android.telephony.UiccPortInfo}.If columns of these 4
-     * classes are changed, we should also update the table except PII data.
-     */
-    public static final class UiccInfoData {
-
-        /** The name of the UiccInfoData table. */
-        public static final String TABLE_NAME = "uiccInfo";
-
-        /**
-         * The name of the ID column, set the {@link SubscriptionInfo#getSubscriptionId()}
-         * as the primary key.
-         */
-        public static final String COLUMN_ID = "sudId";
-
-        /**
-         * The name of the active state column, see {@link UiccPortInfo#isActive()}.
-         */
-        public static final String COLUMN_IS_ACTIVE = "isActive";
     }
 
     /**
@@ -139,12 +108,5 @@
          * {@link SubscriptionManager#isActiveSubscriptionId(int)}.
          */
         public static final String COLUMN_IS_ACTIVE_SUBSCRIPTION_ID = "isActiveSubscription";
-
-        /**
-         * The name of the active data subscription state column, see
-         * {@link SubscriptionManager#getActiveDataSubscriptionId()}.
-         */
-        public static final String COLUMN_IS_ACTIVE_DATA_SUBSCRIPTION =
-                "isActiveDataSubscriptionId";
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkDatabase.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkDatabase.java
index 5f7fa27..6357382 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkDatabase.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkDatabase.java
@@ -27,7 +27,7 @@
 import java.util.List;
 import java.util.Objects;
 
-@Database(entities = {SubscriptionInfoEntity.class, UiccInfoEntity.class,
+@Database(entities = {SubscriptionInfoEntity.class,
         MobileNetworkInfoEntity.class}, exportSchema = false, version = 1)
 public abstract class MobileNetworkDatabase extends RoomDatabase {
 
@@ -35,8 +35,6 @@
 
     public abstract SubscriptionInfoDao mSubscriptionInfoDao();
 
-    public abstract UiccInfoDao mUiccInfoDao();
-
     public abstract MobileNetworkInfoDao mMobileNetworkInfoDao();
 
     private static MobileNetworkDatabase sInstance;
@@ -73,16 +71,6 @@
     }
 
     /**
-     * Insert the UICC info to the UiccInfoEntity table.
-     *
-     * @param uiccInfoEntity The uiccInfoEntity.
-     */
-    public void insertUiccInfo(UiccInfoEntity... uiccInfoEntity) {
-        Log.d(TAG, "insertUiccInfo");
-        mUiccInfoDao().insertUiccInfo(uiccInfoEntity);
-    }
-
-    /**
      * Insert the mobileNetwork info to the MobileNetworkInfoEntity table.
      *
      * @param mobileNetworkInfoEntity The mobileNetworkInfoEntity.
@@ -100,14 +88,6 @@
     }
 
     /**
-     * Query the subscription info by the subscription ID from the SubscriptionInfoEntity
-     * table.
-     */
-    public SubscriptionInfoEntity querySubInfoById(String id) {
-        return mSubscriptionInfoDao().querySubInfoById(id);
-    }
-
-    /**
      * Query all mobileNetwork infos from the MobileNetworkInfoEntity
      * table.
      */
@@ -116,21 +96,6 @@
     }
 
     /**
-     * Query the mobileNetwork info by the subscription ID from the MobileNetworkInfoEntity
-     * table.
-     */
-    public MobileNetworkInfoEntity queryMobileNetworkInfoById(String id) {
-        return mMobileNetworkInfoDao().queryMobileNetworkInfoBySubId(id);
-    }
-
-    /**
-     * Query all UICC infos from the UiccInfoEntity table.
-     */
-    public LiveData<List<UiccInfoEntity>> queryAllUiccInfo() {
-        return mUiccInfoDao().queryAllUiccInfos();
-    }
-
-    /**
      * Delete the subscriptionInfo info by the subscription ID from the SubscriptionInfoEntity
      * table.
      */
@@ -145,11 +110,4 @@
     public void deleteMobileNetworkInfoBySubId(String id) {
         mMobileNetworkInfoDao().deleteBySubId(id);
     }
-
-    /**
-     * Delete the UICC info by the subscription ID from the UiccInfoEntity table.
-     */
-    public void deleteUiccInfoBySubId(String id) {
-        mUiccInfoDao().deleteBySubId(id);
-    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkInfoEntity.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkInfoEntity.java
index 13f99e9..6366708 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkInfoEntity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkInfoEntity.java
@@ -26,11 +26,9 @@
 @Entity(tableName = DataServiceUtils.MobileNetworkInfoData.TABLE_NAME)
 public class MobileNetworkInfoEntity {
 
-    public MobileNetworkInfoEntity(@NonNull String subId, boolean isMobileDataEnabled,
-            boolean showToggleForPhysicalSim) {
+    public MobileNetworkInfoEntity(@NonNull String subId, boolean isMobileDataEnabled) {
         this.subId = subId;
         this.isMobileDataEnabled = isMobileDataEnabled;
-        this.showToggleForPhysicalSim = showToggleForPhysicalSim;
     }
 
     @PrimaryKey
@@ -41,15 +39,11 @@
     @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_MOBILE_DATA_ENABLED)
     public boolean isMobileDataEnabled;
 
-    @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_SHOW_TOGGLE_FOR_PHYSICAL_SIM)
-    public boolean showToggleForPhysicalSim;
-
     @Override
     public int hashCode() {
         int result = 17;
         result = 31 * result + subId.hashCode();
         result = 31 * result + Boolean.hashCode(isMobileDataEnabled);
-        result = 31 * result + Boolean.hashCode(showToggleForPhysicalSim);
         return result;
     }
 
@@ -64,8 +58,7 @@
 
         MobileNetworkInfoEntity info = (MobileNetworkInfoEntity) obj;
         return  TextUtils.equals(subId, info.subId)
-                && isMobileDataEnabled == info.isMobileDataEnabled
-                && showToggleForPhysicalSim == info.showToggleForPhysicalSim;
+                && isMobileDataEnabled == info.isMobileDataEnabled;
     }
 
     public String toString() {
@@ -74,8 +67,6 @@
                 .append(subId)
                 .append(", isMobileDataEnabled = ")
                 .append(isMobileDataEnabled)
-                .append(", activeNetworkIsCellular = ")
-                .append(showToggleForPhysicalSim)
                 .append(")}");
         return builder.toString();
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoEntity.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoEntity.java
index 88e6a57..ff0f27b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoEntity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/SubscriptionInfoEntity.java
@@ -30,7 +30,7 @@
     public SubscriptionInfoEntity(@NonNull String subId, int simSlotIndex, boolean isEmbedded,
             boolean isOpportunistic, String uniqueName, boolean isSubscriptionVisible,
             boolean isDefaultSubscriptionSelection, boolean isValidSubscription,
-            boolean isActiveSubscriptionId, boolean isActiveDataSubscriptionId) {
+            boolean isActiveSubscriptionId) {
         this.subId = subId;
         this.simSlotIndex = simSlotIndex;
         this.isEmbedded = isEmbedded;
@@ -40,7 +40,6 @@
         this.isDefaultSubscriptionSelection = isDefaultSubscriptionSelection;
         this.isValidSubscription = isValidSubscription;
         this.isActiveSubscriptionId = isActiveSubscriptionId;
-        this.isActiveDataSubscriptionId = isActiveDataSubscriptionId;
     }
 
     @PrimaryKey
@@ -73,17 +72,10 @@
     @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_IS_ACTIVE_SUBSCRIPTION_ID)
     public boolean isActiveSubscriptionId;
 
-    @ColumnInfo(name = DataServiceUtils.SubscriptionInfoData.COLUMN_IS_ACTIVE_DATA_SUBSCRIPTION)
-    public boolean isActiveDataSubscriptionId;
-
     public int getSubId() {
         return Integer.valueOf(subId);
     }
 
-    public CharSequence getUniqueDisplayName() {
-        return uniqueName;
-    }
-
     public boolean isActiveSubscription() {
         return isActiveSubscriptionId;
     }
@@ -103,8 +95,7 @@
                 isSubscriptionVisible,
                 isDefaultSubscriptionSelection,
                 isValidSubscription,
-                isActiveSubscriptionId,
-                isActiveDataSubscriptionId);
+                isActiveSubscriptionId);
     }
 
     @Override
@@ -125,8 +116,7 @@
                 && isSubscriptionVisible == info.isSubscriptionVisible
                 && isDefaultSubscriptionSelection == info.isDefaultSubscriptionSelection
                 && isValidSubscription == info.isValidSubscription
-                && isActiveSubscriptionId == info.isActiveSubscriptionId
-                && isActiveDataSubscriptionId == info.isActiveDataSubscriptionId;
+                && isActiveSubscriptionId == info.isActiveSubscriptionId;
     }
 
     public String toString() {
@@ -149,8 +139,6 @@
                 .append(isValidSubscription)
                 .append(", isActiveSubscriptionId = ")
                 .append(isActiveSubscriptionId)
-                .append(", isActiveDataSubscriptionId = ")
-                .append(isActiveDataSubscriptionId)
                 .append(")}");
         return builder.toString();
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/UiccInfoDao.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/UiccInfoDao.java
deleted file mode 100644
index 90e5189..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/UiccInfoDao.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.settingslib.mobile.dataservice;
-
-import androidx.lifecycle.LiveData;
-import androidx.room.Dao;
-import androidx.room.Insert;
-import androidx.room.OnConflictStrategy;
-import androidx.room.Query;
-
-import java.util.List;
-
-@Dao
-public interface UiccInfoDao {
-
-    @Insert(onConflict = OnConflictStrategy.REPLACE)
-    void insertUiccInfo(UiccInfoEntity... uiccInfo);
-
-    @Query("SELECT * FROM " + DataServiceUtils.UiccInfoData.TABLE_NAME + " ORDER BY "
-            + DataServiceUtils.UiccInfoData.COLUMN_ID)
-    LiveData<List<UiccInfoEntity>> queryAllUiccInfos();
-
-    @Query("SELECT COUNT(*) FROM " + DataServiceUtils.UiccInfoData.TABLE_NAME)
-    int count();
-
-    @Query("DELETE FROM " + DataServiceUtils.UiccInfoData.TABLE_NAME + " WHERE "
-            + DataServiceUtils.UiccInfoData.COLUMN_ID + " = :id")
-    void deleteBySubId(String id);
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/UiccInfoEntity.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/UiccInfoEntity.java
deleted file mode 100644
index 0f80edf..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/UiccInfoEntity.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.settingslib.mobile.dataservice;
-
-import android.text.TextUtils;
-
-import androidx.annotation.NonNull;
-import androidx.room.ColumnInfo;
-import androidx.room.Entity;
-import androidx.room.PrimaryKey;
-
-@Entity(tableName = DataServiceUtils.UiccInfoData.TABLE_NAME)
-public class UiccInfoEntity {
-
-    public UiccInfoEntity(@NonNull String subId, boolean isActive) {
-        this.subId = subId;
-        this.isActive = isActive;
-    }
-
-    @PrimaryKey
-    @ColumnInfo(name = DataServiceUtils.UiccInfoData.COLUMN_ID, index = true)
-    @NonNull
-    public String subId;
-
-    @ColumnInfo(name = DataServiceUtils.UiccInfoData.COLUMN_IS_ACTIVE)
-    public boolean isActive;
-
-    @Override
-    public int hashCode() {
-        int result = 17;
-        result = 31 * result + subId.hashCode();
-        result = 31 * result + Boolean.hashCode(isActive);
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof UiccInfoEntity)) {
-            return false;
-        }
-
-        UiccInfoEntity info = (UiccInfoEntity) obj;
-        return TextUtils.equals(subId, info.subId) && isActive == info.isActive;
-    }
-
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append(" {UiccInfoEntity(subId = ")
-                .append(subId)
-                .append(", isActive = ")
-                .append(isActive)
-                .append(")}");
-        return builder.toString();
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
index c71b19c..e01f279 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
@@ -501,7 +501,7 @@
                 val wifiManager = context.getSystemService(WifiManager::class.java) ?: return@launch
                 val aapmManager = context.getSystemService(AdvancedProtectionManager::class.java)
                 if (isAdvancedProtectionEnabled(aapmManager)) {
-                    val intent = AdvancedProtectionManager.createSupportIntent(
+                    val intent = aapmManager.createSupportIntent(
                         AdvancedProtectionManager.FEATURE_ID_DISALLOW_WEP,
                         AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION)
                     onStartActivity(intent)
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index 05f471f..69e99c6 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -33,21 +33,37 @@
 import android.content.Context;
 import android.os.Parcel;
 import android.os.ParcelUuid;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.google.common.collect.ImmutableList;
 
 import org.junit.Before;
 import org.junit.Ignore;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 
 @RunWith(RobolectricTestRunner.class)
 public class CachedBluetoothDeviceManagerTest {
+    @Rule
+    public MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+
     private final static String DEVICE_NAME_1 = "TestName_1";
     private final static String DEVICE_NAME_2 = "TestName_2";
     private final static String DEVICE_NAME_3 = "TestName_3";
@@ -82,6 +98,8 @@
     @Mock
     private HearingAidProfile mHearingAidProfile;
     @Mock
+    private HapClientProfile mHapClientProfile;
+    @Mock
     private CsipSetCoordinatorProfile mCsipSetCoordinatorProfile;
     @Mock
     private BluetoothDevice mDevice1;
@@ -89,12 +107,11 @@
     private BluetoothDevice mDevice2;
     @Mock
     private BluetoothDevice mDevice3;
+    private HearingAidDeviceManager mHearingAidDeviceManager;
     private CachedBluetoothDevice mCachedDevice1;
     private CachedBluetoothDevice mCachedDevice2;
     private CachedBluetoothDevice mCachedDevice3;
     private CachedBluetoothDeviceManager mCachedDeviceManager;
-    private HearingAidDeviceManager mHearingAidDeviceManager;
-    private Context mContext;
 
     private BluetoothClass createBtClass(int deviceClass) {
         Parcel p = Parcel.obtain();
@@ -108,8 +125,6 @@
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
         when(mDevice1.getAddress()).thenReturn(DEVICE_ADDRESS_1);
         when(mDevice2.getAddress()).thenReturn(DEVICE_ADDRESS_2);
         when(mDevice3.getAddress()).thenReturn(DEVICE_ADDRESS_3);
@@ -129,13 +144,15 @@
         when(mA2dpProfile.isProfileReady()).thenReturn(true);
         when(mPanProfile.isProfileReady()).thenReturn(true);
         when(mHearingAidProfile.isProfileReady()).thenReturn(true);
+        when(mHapClientProfile.isProfileReady()).thenReturn(true);
         when(mCsipSetCoordinatorProfile.isProfileReady())
                 .thenReturn(true);
         doAnswer((invocation) -> mHearingAidProfile).
                 when(mLocalProfileManager).getHearingAidProfile();
         doAnswer((invocation) -> mCsipSetCoordinatorProfile)
                 .when(mLocalProfileManager).getCsipSetCoordinatorProfile();
-        mCachedDeviceManager = new CachedBluetoothDeviceManager(mContext, mLocalBluetoothManager);
+        mCachedDeviceManager = spy(
+                new CachedBluetoothDeviceManager(mContext, mLocalBluetoothManager));
         mCachedDevice1 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice1));
         mCachedDevice2 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice2));
         mCachedDevice3 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice3));
@@ -621,12 +638,55 @@
     public void onActiveDeviceChanged_validHiSyncId_callExpectedFunction() {
         doNothing().when(mHearingAidDeviceManager).onActiveDeviceChanged(any());
         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
-        CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
-        cachedDevice1.setHearingAidInfo(
-                new HearingAidInfo.Builder().setHiSyncId(HISYNCID1).build());
+        when(mCachedDevice1.getProfiles()).thenReturn(
+                ImmutableList.of(mHapClientProfile, mHearingAidProfile));
 
-        mCachedDeviceManager.onActiveDeviceChanged(cachedDevice1);
+        mCachedDeviceManager.onActiveDeviceChanged(mCachedDevice1);
 
-        verify(mHearingAidDeviceManager).onActiveDeviceChanged(cachedDevice1);
+        verify(mHearingAidDeviceManager).onActiveDeviceChanged(mCachedDevice1);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(
+            com.android.settingslib.flags.Flags.FLAG_HEARING_DEVICE_SET_CONNECTION_STATUS_REPORT)
+    public void onActiveDeviceChanged_hearingDevice_callReportConnectionStatus() {
+        when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mCachedDevice1.getProfiles()).thenReturn(
+                ImmutableList.of(mHapClientProfile, mHearingAidProfile));
+
+        mCachedDeviceManager.onActiveDeviceChanged(mCachedDevice1);
+
+        verify(mHearingAidDeviceManager).notifyDevicesConnectionStatusChanged();
+    }
+
+    @Test
+    @RequiresFlagsEnabled(
+            com.android.settingslib.flags.Flags.FLAG_HEARING_DEVICE_SET_CONNECTION_STATUS_REPORT)
+    public void onDeviceUnpaired_hearingDevice_callReportConnectionStatus() {
+        when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mCachedDevice1.getProfiles()).thenReturn(
+                ImmutableList.of(mHapClientProfile, mHearingAidProfile));
+
+        mCachedDeviceManager.onDeviceUnpaired(mCachedDevice1);
+
+        verify(mHearingAidDeviceManager).notifyDevicesConnectionStatusChanged();
+    }
+
+    @Test
+    public void notifyHearingDevicesConnectionStatusChanged_nonHearingDevice_notCallFunction() {
+        when(mCachedDevice1.getProfiles()).thenReturn(List.of(mA2dpProfile));
+
+        mCachedDeviceManager.notifyHearingDevicesConnectionStatusChangedIfNeeded(mCachedDevice1);
+
+        verify(mHearingAidDeviceManager, never()).notifyDevicesConnectionStatusChanged();
+    }
+
+    @Test
+    public void notifyHearingDevicesConnectionStatusChanged_hearingDeviceProfile_callFunction() {
+        when(mCachedDevice1.getProfiles()).thenReturn(List.of(mHapClientProfile));
+
+        mCachedDeviceManager.notifyHearingDevicesConnectionStatusChangedIfNeeded(mCachedDevice1);
+
+        verify(mHearingAidDeviceManager).notifyDevicesConnectionStatusChanged();
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 30f8a79..d933a1c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -2074,6 +2074,21 @@
         assertThat(mCachedDevice.getConnectionSummary(false)).isNull();
     }
 
+    @Test
+    public void isHearingDevice_supportHearingRelatedProfiles_returnTrue() {
+        when(mCachedDevice.getProfiles()).thenReturn(
+                ImmutableList.of(mHapClientProfile, mHearingAidProfile));
+
+        assertThat(mCachedDevice.isHearingDevice()).isTrue();
+    }
+
+    @Test
+    public void isHearingDevice_supportOnlyLeAudioProfile_returnFalse() {
+        when(mCachedDevice.getProfiles()).thenReturn(ImmutableList.of(mLeAudioProfile));
+
+        assertThat(mCachedDevice.isHearingDevice()).isFalse();
+    }
+
     private void updateProfileStatus(LocalBluetoothProfile profile, int status) {
         doReturn(status).when(profile).getConnectionStatus(mDevice);
         mCachedDevice.onProfileStateChanged(profile, status);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelperTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelperTest.java
index c835244..dc609bd 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelperTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidAudioRoutingHelperTest.java
@@ -16,9 +16,14 @@
 
 package com.android.settingslib.bluetooth;
 
+import static com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants.BUILTIN_MIC;
+import static com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants.BUILTIN_SPEAKER;
+import static com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants.MICROPHONE_SOURCE_VOICE_COMMUNICATION;
+
 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.atLeastOnce;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
@@ -35,10 +40,13 @@
 
 import androidx.test.core.app.ApplicationProvider;
 
+import com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants.RoutingValue;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.Spy;
 import org.mockito.junit.MockitoJUnit;
@@ -67,28 +75,35 @@
     @Spy
     private AudioManager mAudioManager = mContext.getSystemService(AudioManager.class);
     @Mock
-    private AudioDeviceInfo mAudioDeviceInfo;
+    private AudioDeviceInfo mHearingDeviceInfoOutput;
+    @Mock
+    private AudioDeviceInfo mLeHearingDeviceInfoInput;
     @Mock
     private CachedBluetoothDevice mCachedBluetoothDevice;
     @Mock
     private CachedBluetoothDevice mSubCachedBluetoothDevice;
-    private AudioDeviceAttributes mHearingDeviceAttribute;
+    private AudioDeviceAttributes mHearingDeviceAttributeOutput;
     private HearingAidAudioRoutingHelper mHelper;
 
     @Before
     public void setUp() {
         doReturn(mAudioManager).when(mContext).getSystemService(AudioManager.class);
-        when(mAudioDeviceInfo.getType()).thenReturn(AudioDeviceInfo.TYPE_HEARING_AID);
-        when(mAudioDeviceInfo.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
+        when(mHearingDeviceInfoOutput.getType()).thenReturn(AudioDeviceInfo.TYPE_HEARING_AID);
+        when(mHearingDeviceInfoOutput.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
+        when(mLeHearingDeviceInfoInput.getType()).thenReturn(AudioDeviceInfo.TYPE_BLE_HEADSET);
+        when(mLeHearingDeviceInfoInput.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
+        when(mCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
         when(mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)).thenReturn(
-                new AudioDeviceInfo[]{mAudioDeviceInfo});
+                new AudioDeviceInfo[]{mHearingDeviceInfoOutput});
+        when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(
+                new AudioDeviceInfo[]{mLeHearingDeviceInfoInput});
         doReturn(Collections.emptyList()).when(mAudioManager).getPreferredDevicesForStrategy(
                 any(AudioProductStrategy.class));
         when(mAudioStrategy.getAudioAttributesForLegacyStreamType(
                 AudioManager.STREAM_MUSIC))
                 .thenReturn((new AudioAttributes.Builder()).build());
 
-        mHearingDeviceAttribute = new AudioDeviceAttributes(
+        mHearingDeviceAttributeOutput = new AudioDeviceAttributes(
                 AudioDeviceAttributes.ROLE_OUTPUT,
                 AudioDeviceInfo.TYPE_HEARING_AID,
                 TEST_DEVICE_ADDRESS);
@@ -99,11 +114,10 @@
     @Test
     public void setPreferredDeviceRoutingStrategies_hadValueThenValueAuto_callRemoveStrategy() {
         when(mAudioManager.getPreferredDeviceForStrategy(mAudioStrategy)).thenReturn(
-                mHearingDeviceAttribute);
+                mHearingDeviceAttributeOutput);
 
         mHelper.setPreferredDeviceRoutingStrategies(List.of(mAudioStrategy),
-                mHearingDeviceAttribute,
-                HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+                mHearingDeviceAttributeOutput, RoutingValue.AUTO);
 
         verify(mAudioManager, atLeastOnce()).removePreferredDeviceForStrategy(mAudioStrategy);
     }
@@ -113,8 +127,7 @@
         when(mAudioManager.getPreferredDeviceForStrategy(mAudioStrategy)).thenReturn(null);
 
         mHelper.setPreferredDeviceRoutingStrategies(List.of(mAudioStrategy),
-                mHearingDeviceAttribute,
-                HearingAidAudioRoutingConstants.RoutingValue.AUTO);
+                mHearingDeviceAttributeOutput, RoutingValue.AUTO);
 
         verify(mAudioManager, never()).removePreferredDeviceForStrategy(mAudioStrategy);
     }
@@ -122,63 +135,95 @@
     @Test
     public void setPreferredDeviceRoutingStrategies_valueHearingDevice_callSetStrategy() {
         mHelper.setPreferredDeviceRoutingStrategies(List.of(mAudioStrategy),
-                mHearingDeviceAttribute,
-                HearingAidAudioRoutingConstants.RoutingValue.HEARING_DEVICE);
+                mHearingDeviceAttributeOutput, RoutingValue.HEARING_DEVICE);
 
         verify(mAudioManager, atLeastOnce()).setPreferredDeviceForStrategy(mAudioStrategy,
-                mHearingDeviceAttribute);
+                mHearingDeviceAttributeOutput);
     }
 
     @Test
-    public void setPreferredDeviceRoutingStrategies_valueDeviceSpeaker_callSetStrategy() {
-        final AudioDeviceAttributes speakerDevice = new AudioDeviceAttributes(
-                AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, "");
+    public void setPreferredDeviceRoutingStrategies_valueBuiltinDevice_callSetStrategy() {
         mHelper.setPreferredDeviceRoutingStrategies(List.of(mAudioStrategy),
-                mHearingDeviceAttribute,
-                HearingAidAudioRoutingConstants.RoutingValue.DEVICE_SPEAKER);
+                mHearingDeviceAttributeOutput, RoutingValue.BUILTIN_DEVICE);
 
         verify(mAudioManager, atLeastOnce()).setPreferredDeviceForStrategy(mAudioStrategy,
-                speakerDevice);
+                BUILTIN_SPEAKER);
     }
 
     @Test
-    public void getMatchedHearingDeviceAttributes_mainHearingDevice_equalAddress() {
+    public void getMatchedHearingDeviceAttributesForOutput_mainHearingDevice_equalAddress() {
         when(mCachedBluetoothDevice.isHearingAidDevice()).thenReturn(true);
         when(mCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
 
-        final String targetAddress = mHelper.getMatchedHearingDeviceAttributes(
+        final String targetAddress = mHelper.getMatchedHearingDeviceAttributesForOutput(
                 mCachedBluetoothDevice).getAddress();
 
-        assertThat(targetAddress).isEqualTo(mHearingDeviceAttribute.getAddress());
+        assertThat(targetAddress).isEqualTo(mHearingDeviceAttributeOutput.getAddress());
     }
 
     @Test
-    public void getMatchedHearingDeviceAttributes_subHearingDevice_equalAddress() {
+    public void getMatchedHearingDeviceAttributesForOutput_subHearingDevice_equalAddress() {
         when(mCachedBluetoothDevice.isHearingAidDevice()).thenReturn(true);
         when(mCachedBluetoothDevice.getAddress()).thenReturn(NOT_EXPECT_DEVICE_ADDRESS);
         when(mCachedBluetoothDevice.getSubDevice()).thenReturn(mSubCachedBluetoothDevice);
         when(mSubCachedBluetoothDevice.isHearingAidDevice()).thenReturn(true);
         when(mSubCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
 
-        final String targetAddress = mHelper.getMatchedHearingDeviceAttributes(
+        final String targetAddress = mHelper.getMatchedHearingDeviceAttributesForOutput(
                 mCachedBluetoothDevice).getAddress();
 
-        assertThat(targetAddress).isEqualTo(mHearingDeviceAttribute.getAddress());
+        assertThat(targetAddress).isEqualTo(mHearingDeviceAttributeOutput.getAddress());
     }
 
     @Test
-    public void getMatchedHearingDeviceAttributes_memberHearingDevice_equalAddress() {
+    public void getMatchedHearingDeviceAttributesForOutput_memberHearingDevice_equalAddress() {
         when(mSubCachedBluetoothDevice.isHearingAidDevice()).thenReturn(true);
         when(mSubCachedBluetoothDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS);
-        final Set<CachedBluetoothDevice> memberDevices = new HashSet<CachedBluetoothDevice>();
+        final Set<CachedBluetoothDevice> memberDevices = new HashSet<>();
         memberDevices.add(mSubCachedBluetoothDevice);
         when(mCachedBluetoothDevice.isHearingAidDevice()).thenReturn(true);
         when(mCachedBluetoothDevice.getAddress()).thenReturn(NOT_EXPECT_DEVICE_ADDRESS);
         when(mCachedBluetoothDevice.getMemberDevice()).thenReturn(memberDevices);
 
-        final String targetAddress = mHelper.getMatchedHearingDeviceAttributes(
+        final String targetAddress = mHelper.getMatchedHearingDeviceAttributesForOutput(
                 mCachedBluetoothDevice).getAddress();
 
-        assertThat(targetAddress).isEqualTo(mHearingDeviceAttribute.getAddress());
+        assertThat(targetAddress).isEqualTo(mHearingDeviceAttributeOutput.getAddress());
+    }
+
+    @Test
+    public void setPreferredInputDeviceForCalls_valueAuto_callClearPreset() {
+        when(mCachedBluetoothDevice.isHearingAidDevice()).thenReturn(true);
+
+        mHelper.setPreferredInputDeviceForCalls(mCachedBluetoothDevice, RoutingValue.AUTO);
+
+        verify(mAudioManager).clearPreferredDevicesForCapturePreset(
+                MICROPHONE_SOURCE_VOICE_COMMUNICATION);
+    }
+
+    @Test
+    public void setPreferredInputDeviceForCalls_valueHearingDevice_callSetPresetToHearingDevice() {
+        final ArgumentCaptor<AudioDeviceAttributes> audioDeviceAttributesCaptor =
+                ArgumentCaptor.forClass(AudioDeviceAttributes.class);
+        when(mCachedBluetoothDevice.isHearingAidDevice()).thenReturn(true);
+
+        mHelper.setPreferredInputDeviceForCalls(mCachedBluetoothDevice,
+                RoutingValue.HEARING_DEVICE);
+
+        verify(mAudioManager).setPreferredDeviceForCapturePreset(
+                eq(MICROPHONE_SOURCE_VOICE_COMMUNICATION), audioDeviceAttributesCaptor.capture());
+        assertThat(audioDeviceAttributesCaptor.getValue().getAddress()).isEqualTo(
+                TEST_DEVICE_ADDRESS);
+    }
+
+    @Test
+    public void setPreferredInputDeviceForCalls_valueBuiltinDevice_callClearPresetToBuiltinMic() {
+        when(mCachedBluetoothDevice.isHearingAidDevice()).thenReturn(true);
+
+        mHelper.setPreferredInputDeviceForCalls(mCachedBluetoothDevice,
+                RoutingValue.BUILTIN_DEVICE);
+
+        verify(mAudioManager).setPreferredDeviceForCapturePreset(
+                MICROPHONE_SOURCE_VOICE_COMMUNICATION, BUILTIN_MIC);
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
index eb73eee..21dde1f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java
@@ -54,6 +54,8 @@
 
 import androidx.test.core.app.ApplicationProvider;
 
+import com.android.settingslib.bluetooth.HearingAidDeviceManager.ConnectionStatus;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -112,7 +114,10 @@
     private BluetoothDevice mDevice1;
     @Mock
     private BluetoothDevice mDevice2;
-
+    @Mock
+    private HearingAidDeviceManager.ConnectionStatusListener mConnectionStatusListener;
+    @Mock
+    private HearingAidDeviceManager.ConnectionStatusListener mConnectionStatusListener2;
 
     private BluetoothClass createBtClass(int deviceClass) {
         Parcel p = Parcel.obtain();
@@ -140,6 +145,8 @@
         when(mLocalProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
         when(mLocalProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile);
         when(mLocalProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile);
+        when(mHapClientProfile.getProfileId()).thenReturn(BluetoothProfile.HAP_CLIENT);
+        when(mLeAudioProfile.getProfileId()).thenReturn(BluetoothProfile.LE_AUDIO);
         when(mAudioStrategy.getAudioAttributesForLegacyStreamType(
                 AudioManager.STREAM_MUSIC))
                 .thenReturn((new AudioAttributes.Builder()).build());
@@ -729,7 +736,7 @@
 
     @Test
     public void onActiveDeviceChanged_connected_callSetStrategies() {
-        when(mHelper.getMatchedHearingDeviceAttributes(mCachedDevice1)).thenReturn(
+        when(mHelper.getMatchedHearingDeviceAttributesForOutput(mCachedDevice1)).thenReturn(
                 mHearingDeviceAttribute);
         when(mCachedDevice1.isActiveDevice(BluetoothProfile.HEARING_AID)).thenReturn(true);
         doReturn(true).when(mHelper).setPreferredDeviceRoutingStrategies(anyList(),
@@ -743,7 +750,7 @@
 
     @Test
     public void onActiveDeviceChanged_disconnected_callSetStrategiesWithAutoValue() {
-        when(mHelper.getMatchedHearingDeviceAttributes(mCachedDevice1)).thenReturn(
+        when(mHelper.getMatchedHearingDeviceAttributesForOutput(mCachedDevice1)).thenReturn(
                 mHearingDeviceAttribute);
         when(mCachedDevice1.isActiveDevice(BluetoothProfile.HEARING_AID)).thenReturn(false);
         doReturn(true).when(mHelper).setPreferredDeviceRoutingStrategies(anyList(), any(),
@@ -826,6 +833,125 @@
         verify(mHapClientProfile).selectPreset(mDevice2, PRESET_INDEX_1);
     }
 
+    @Test
+    public void getAssociatedCachedDevice_existSubDevice_returnSize2() {
+        mCachedDevice1.setSubDevice(mCachedDevice2);
+
+        //including self device
+        assertThat(mHearingAidDeviceManager.getAssociatedCachedDevice(
+                mCachedDevice1).size()).isEqualTo(2);
+    }
+
+    @Test
+    public void getAssociatedCachedDevice_existMemberDevice_returnSize2() {
+        mCachedDevice1.addMemberDevice(mCachedDevice2);
+
+        //including self device
+        assertThat(mHearingAidDeviceManager.getAssociatedCachedDevice(
+                mCachedDevice1).size()).isEqualTo(2);
+    }
+
+    @Test
+    public void notifyDevicesConnectionStatusChanged_connecting_connectingStatus() {
+        when(mCachedDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mCachedDevice1.getProfiles()).thenReturn(List.of(mHapClientProfile));
+        when(mHapClientProfile.getConnectionStatus(mDevice1)).thenReturn(
+                BluetoothProfile.STATE_CONNECTING);
+
+        mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
+        mHearingAidDeviceManager.notifyDevicesConnectionStatusChanged();
+
+        assertThat(mHearingAidDeviceManager.getDevicesConnectionStatus()).isEqualTo(
+                ConnectionStatus.CONNECTING_OR_DISCONNECTING);
+    }
+
+    @Test
+    public void notifyDevicesConnectionStatusChanged_activeConnectedProfile_activeStatus() {
+        when(mCachedDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mCachedDevice1.getProfiles()).thenReturn(List.of(mHapClientProfile, mLeAudioProfile));
+        when(mLeAudioProfile.getConnectionStatus(mDevice1)).thenReturn(
+                BluetoothProfile.STATE_CONNECTED);
+        when(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true);
+
+        mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
+        mHearingAidDeviceManager.notifyDevicesConnectionStatusChanged();
+
+        assertThat(mHearingAidDeviceManager.getDevicesConnectionStatus()).isEqualTo(
+                ConnectionStatus.ACTIVE);
+    }
+
+    @Test
+    public void notifyDevicesConnectionStatusChanged_isConnected_connectedStatus() {
+        when(mCachedDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mCachedDevice1.getProfiles()).thenReturn(List.of(mHapClientProfile, mLeAudioProfile));
+        when(mCachedDevice1.isConnected()).thenReturn(true);
+
+        mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
+        mHearingAidDeviceManager.notifyDevicesConnectionStatusChanged();
+
+        assertThat(mHearingAidDeviceManager.getDevicesConnectionStatus()).isEqualTo(
+                ConnectionStatus.CONNECTED);
+    }
+
+    @Test
+    public void notifyDevicesConnectionStatusChanged_bondedNotConnected_disconnectedStatus() {
+        when(mCachedDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mCachedDevice1.isConnected()).thenReturn(false);
+        when(mCachedDevice1.getProfiles()).thenReturn(List.of(mHapClientProfile));
+        mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
+
+        mHearingAidDeviceManager.notifyDevicesConnectionStatusChanged();
+
+        assertThat(mHearingAidDeviceManager.getDevicesConnectionStatus()).isEqualTo(
+                ConnectionStatus.DISCONNECTED);
+    }
+
+    @Test
+    public void notifyDevicesConnectionStatusChanged_bondNone_noDeviceBondedStatus() {
+        when(mCachedDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
+        mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
+
+        mHearingAidDeviceManager.notifyDevicesConnectionStatusChanged();
+
+        assertThat(mHearingAidDeviceManager.getDevicesConnectionStatus()).isEqualTo(
+                ConnectionStatus.NO_DEVICE_BONDED);
+    }
+
+    @Test
+    public void notifyDevicesConnectionStatusChanged_noRegisteredListener_noCallback() {
+        when(mCachedDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mCachedDevice1.getProfiles()).thenReturn(List.of(mHapClientProfile, mLeAudioProfile));
+        when(mCachedDevice1.isConnected()).thenReturn(true);
+        mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
+
+        mHearingAidDeviceManager.registerConnectionStatusListener(
+                mConnectionStatusListener, mContext.getMainExecutor());
+        mHearingAidDeviceManager.unregisterConnectionStatusListener(
+                mConnectionStatusListener);
+        mHearingAidDeviceManager.notifyDevicesConnectionStatusChanged();
+
+        verify(mConnectionStatusListener, never()).onDevicesConnectionStatusChanged(anyInt());
+    }
+
+    @Test
+    public void notifyDevicesConnectionStatusChanged_twoRegisteredListener_callbackEachConnected() {
+        when(mCachedDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mCachedDevice1.getProfiles()).thenReturn(List.of(mHapClientProfile, mLeAudioProfile));
+        when(mCachedDevice1.isConnected()).thenReturn(true);
+        mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
+
+        mHearingAidDeviceManager.registerConnectionStatusListener(
+                mConnectionStatusListener, mContext.getMainExecutor());
+        mHearingAidDeviceManager.registerConnectionStatusListener(
+                mConnectionStatusListener2, mContext.getMainExecutor());
+        mHearingAidDeviceManager.notifyDevicesConnectionStatusChanged();
+
+        verify(mConnectionStatusListener).onDevicesConnectionStatusChanged(
+                ConnectionStatus.CONNECTED);
+        verify(mConnectionStatusListener2).onDevicesConnectionStatusChanged(
+                ConnectionStatus.CONNECTED);
+    }
+
     private HearingAidInfo getLeftAshaHearingAidInfo(long hiSyncId) {
         return new HearingAidInfo.Builder()
                 .setAshaDeviceSide(HearingAidInfo.DeviceSide.SIDE_LEFT)
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
index 6ff90ba..219bfe0 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
@@ -37,10 +37,14 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.ParcelUuid;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 
 import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -56,6 +60,9 @@
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {ShadowBluetoothAdapter.class})
 public class LocalBluetoothProfileManagerTest {
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
     private static final long HISYNCID = 10;
 
     private static final int GROUP_ID = 1;
@@ -305,6 +312,25 @@
         verify(mCachedBluetoothDevice).refresh();
     }
 
+    @Test
+    @RequiresFlagsEnabled(
+            com.android.settingslib.flags.Flags.FLAG_HEARING_DEVICE_SET_CONNECTION_STATUS_REPORT)
+    public void stateChangedHandler_hapProfileStateChanged_notifyHearingDevicesConnectionStatus() {
+        mShadowBluetoothAdapter.setSupportedProfiles(generateList(
+                new int[] {BluetoothProfile.HAP_CLIENT}));
+        mProfileManager.updateLocalProfiles();
+
+        mIntent = new Intent(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED);
+        mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
+        mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
+        mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
+
+        mContext.sendBroadcast(mIntent);
+
+        verify(mDeviceManager).notifyHearingDevicesConnectionStatusChangedIfNeeded(
+                mCachedBluetoothDevice);
+    }
+
     private List<Integer> generateList(int[] profiles) {
         if (profiles == null) {
             return null;
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 18bebd4..b9f8c71 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -289,5 +289,6 @@
         Settings.Secure.MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED,
         Settings.Secure.ADVANCED_PROTECTION_MODE,
         Settings.Secure.ACCESSIBILITY_KEY_GESTURE_TARGETS,
+        Settings.Secure.EM_VALUE,
     };
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 1d7608d..7c5e577 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -445,6 +445,8 @@
                 Secure.RESOLUTION_MODE_UNKNOWN, Secure.RESOLUTION_MODE_FULL));
         VALIDATORS.put(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_SATURATION_LEVEL,
                 new InclusiveIntegerRangeValidator(0, 10));
+        VALIDATORS.put(Secure.EM_VALUE,
+                new InclusiveIntegerRangeValidator(0, 1));
         VALIDATORS.put(Secure.CHARGE_OPTIMIZATION_MODE, new InclusiveIntegerRangeValidator(0, 10));
         VALIDATORS.put(Secure.ON_DEVICE_INFERENCE_UNBIND_TIMEOUT_MS, ANY_LONG_VALIDATOR);
         VALIDATORS.put(Secure.ON_DEVICE_INTELLIGENCE_UNBIND_TIMEOUT_MS, ANY_LONG_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 661a095..dedd7eb 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2186,6 +2186,10 @@
                 SecureSettingsProto.EvenDimmer.EVEN_DIMMER_MIN_NITS);
         p.end(evenDimmerToken);
 
+        dumpSetting(s, p,
+                Settings.Secure.EM_VALUE,
+                SecureSettingsProto.Accessibility.EM_VALUE);
+
         final long gestureToken = p.start(SecureSettingsProto.GESTURE);
         dumpSetting(s, p,
                 Settings.Secure.AWARE_ENABLED,
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 3ee2db1..b88ae37 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -278,13 +278,13 @@
         "tests/src/**/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt",
         "tests/src/**/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt",
         "tests/src/**/systemui/qs/tiles/HotspotTileTest.java",
-        "tests/src/**/systemui/qs/tiles/dialog/InternetDialogDelegateTest.java",
+        "tests/src/**/systemui/qs/tiles/dialog/InternetDialogDelegateLegacyTest.java",
         "tests/src/**/systemui/navigationbar/NavigationBarControllerImplTest.java",
         "tests/src/**/systemui/wmshell/BubblesTest.java",
         "tests/src/**/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java",
         "tests/src/**/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java",
         "tests/src/**/systemui/shared/system/RemoteTransitionTest.java",
-        "tests/src/**/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java",
+        "tests/src/**/systemui/qs/tiles/dialog/InternetDetailsContentControllerTest.java",
         "tests/src/**/systemui/qs/external/TileLifecycleManagerTest.java",
         "tests/src/**/systemui/ScreenDecorationsTest.java",
         "tests/src/**/systemui/statusbar/policy/BatteryControllerStartableTest.java",
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 87fb58e..8dd7c7a 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -492,7 +492,7 @@
     name: "status_bar_notification_chips"
     namespace: "systemui"
     description: "Show promoted ongoing notifications as chips in the status bar"
-    bug: "361346412"
+    bug: "364653005"
 }
 
 flag {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index 9ab2812..9c53afe 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -20,6 +20,7 @@
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.draw.blur
 import androidx.compose.ui.draw.drawBehind
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.BlendMode
@@ -43,6 +44,7 @@
 import com.android.compose.animation.scene.Swipe
 import com.android.compose.animation.scene.observableTransitionState
 import com.android.compose.animation.scene.transitions
+import com.android.compose.modifiers.thenIf
 import com.android.systemui.communal.shared.model.CommunalBackgroundType
 import com.android.systemui.communal.shared.model.CommunalScenes
 import com.android.systemui.communal.shared.model.CommunalTransitionKeys
@@ -158,6 +160,7 @@
             transitions = sceneTransitions,
         )
     }
+    val isUiBlurred by viewModel.isUiBlurred.collectAsStateWithLifecycle()
 
     val detector = remember { CommunalSwipeDetector() }
 
@@ -174,9 +177,11 @@
         onDispose { viewModel.setTransitionState(null) }
     }
 
+    val blurRadius = with(LocalDensity.current) { viewModel.blurRadiusPx.toDp() }
+
     SceneTransitionLayout(
         state = state,
-        modifier = modifier.fillMaxSize(),
+        modifier = modifier.fillMaxSize().thenIf(isUiBlurred) { Modifier.blur(blurRadius) },
         swipeSourceDetector = detector,
         swipeDetector = detector,
     ) {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index 9bc3343..068df8e 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -112,6 +112,7 @@
 import androidx.compose.runtime.snapshotFlow
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
 import androidx.compose.ui.draw.drawBehind
 import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.focusRequester
@@ -759,10 +760,12 @@
 private fun HorizontalGridWrapper(
     minContentPadding: PaddingValues,
     gridState: LazyGridState,
+    dragDropState: GridDragDropState?,
     setContentOffset: (offset: Offset) -> Unit,
     modifier: Modifier = Modifier,
     content: LazyGridScope.(sizeInfo: SizeInfo?) -> Unit,
 ) {
+    val isDragging = dragDropState?.draggingItemKey != null
     if (communalResponsiveGrid()) {
         val flingBehavior =
             rememberSnapFlingBehavior(lazyGridState = gridState, snapPosition = SnapPosition.Start)
@@ -775,6 +778,10 @@
             minHorizontalArrangement = Dimensions.ItemSpacing,
             minVerticalArrangement = Dimensions.ItemSpacing,
             setContentOffset = setContentOffset,
+            // Temporarily disable user gesture scrolling while dragging a widget to prevent
+            // conflicts between the drag and scroll gestures. Programmatic scrolling remains
+            // enabled to allow dragging a widget beyond the visible boundaries.
+            userScrollEnabled = !isDragging,
             content = content,
         )
     } else {
@@ -793,6 +800,10 @@
             contentPadding = minContentPadding,
             horizontalArrangement = Arrangement.spacedBy(Dimensions.ItemSpacing),
             verticalArrangement = Arrangement.spacedBy(Dimensions.ItemSpacing),
+            // Temporarily disable user gesture scrolling while dragging a widget to prevent
+            // conflicts between the drag and scroll gestures. Programmatic scrolling remains
+            // enabled to allow dragging a widget beyond the visible boundaries.
+            userScrollEnabled = !isDragging,
         ) {
             content(null)
         }
@@ -862,6 +873,7 @@
     HorizontalGridWrapper(
         modifier = gridModifier,
         gridState = gridState,
+        dragDropState = dragDropState,
         minContentPadding = minContentPadding,
         setContentOffset = setContentOffset,
     ) { sizeInfo ->
@@ -1708,23 +1720,29 @@
 private fun UmoLegacy(viewModel: BaseCommunalViewModel, modifier: Modifier = Modifier) {
     AndroidView(
         modifier =
-            modifier.pointerInput(Unit) {
-                detectHorizontalDragGestures { change, _ ->
-                    change.consume()
-                    val upTime = SystemClock.uptimeMillis()
-                    val event =
-                        MotionEvent.obtain(
-                            upTime,
-                            upTime,
-                            MotionEvent.ACTION_MOVE,
-                            change.position.x,
-                            change.position.y,
-                            0,
-                        )
-                    viewModel.mediaHost.hostView.dispatchTouchEvent(event)
-                    event.recycle()
-                }
-            },
+            modifier
+                .clip(
+                    shape =
+                        RoundedCornerShape(dimensionResource(system_app_widget_background_radius))
+                )
+                .background(MaterialTheme.colorScheme.primary)
+                .pointerInput(Unit) {
+                    detectHorizontalDragGestures { change, _ ->
+                        change.consume()
+                        val upTime = SystemClock.uptimeMillis()
+                        val event =
+                            MotionEvent.obtain(
+                                upTime,
+                                upTime,
+                                MotionEvent.ACTION_MOVE,
+                                change.position.x,
+                                change.position.y,
+                                0,
+                            )
+                        viewModel.mediaHost.hostView.dispatchTouchEvent(event)
+                        event.recycle()
+                    }
+                },
         factory = { _ ->
             viewModel.mediaHost.hostView.apply {
                 layoutParams =
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
index 7956d02..9643f19 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
@@ -34,7 +34,6 @@
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.compose.animation.scene.SceneScope
 import com.android.compose.modifiers.padding
-import com.android.compose.modifiers.thenIf
 import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.keyguard.ui.composable.LockscreenLongPress
 import com.android.systemui.keyguard.ui.composable.section.AmbientIndicationSection
@@ -97,18 +96,15 @@
                             )
                         }
 
-                        Box {
+                        Box(modifier = Modifier.fillMaxWidth()) {
                             with(topAreaSection) {
                                 DefaultClockLayout(
                                     smartSpacePaddingTop = viewModel::getSmartSpacePaddingTop,
                                     isShadeLayoutWide = isShadeLayoutWide,
                                     modifier =
-                                        Modifier.thenIf(isShadeLayoutWide) {
-                                                Modifier.fillMaxWidth(0.5f)
-                                            }
-                                            .graphicsLayer {
-                                                translationX = unfoldTranslations.start
-                                            },
+                                        Modifier.fillMaxWidth().graphicsLayer {
+                                            translationX = unfoldTranslations.start
+                                        },
                                 )
                             }
                             if (isShadeLayoutWide && !isBypassEnabled) {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
index eae46e9..fb01e70 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
@@ -81,10 +81,7 @@
                     .padding(horizontal = dimensionResource(R.dimen.clock_padding_start))
                     .padding(top = { smallTopMargin })
                     .onTopPlacementChanged(onTopChanged)
-                    .burnInAware(
-                        viewModel = aodBurnInViewModel,
-                        params = burnInParams,
-                    )
+                    .burnInAware(viewModel = aodBurnInViewModel, params = burnInParams)
                     .element(smallClockElementKey),
         )
     }
@@ -114,10 +111,7 @@
             val dir = if (transition.toContent == splitShadeLargeClockScene) -1f else 1f
             val distance = dir * getClockCenteringDistance()
             val largeClock = checkNotNull(currentClock).largeClock
-            largeClock.animations.onPositionUpdated(
-                distance = distance,
-                fraction = progress,
-            )
+            largeClock.animations.onPositionUpdated(distance = distance, fraction = progress)
         }
 
         Element(key = largeClockElementKey, modifier = modifier) {
@@ -125,6 +119,16 @@
                 AndroidView(
                     factory = { context ->
                         FrameLayout(context).apply {
+                            // By default, ViewGroups like FrameLayout clip their children. Turning
+                            // off the clipping allows the child view to render outside of its
+                            // bounds - letting the step animation of the clock push the digits out
+                            // when needed.
+                            //
+                            // Note that, in Compose, clipping is actually disabled by default so
+                            // there's no need to propagate this up the composable hierarchy.
+                            clipChildren = false
+                            clipToPadding = false
+
                             ensureClockViewExists(checkNotNull(currentClock).largeClock.view)
                         }
                     },
@@ -136,8 +140,8 @@
                             .burnInAware(
                                 viewModel = aodBurnInViewModel,
                                 params = burnInParams,
-                                isClock = true
-                            )
+                                isClock = true,
+                            ),
                 )
             }
         }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
index 957fdf7b..46e0efa 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
@@ -284,8 +284,9 @@
     viewModel: NotificationsPlaceholderViewModel,
     maxScrimTop: () -> Float,
     shouldPunchHoleBehindScrim: Boolean,
+    stackTopPadding: Dp,
+    stackBottomPadding: Dp,
     shouldFillMaxSize: Boolean = true,
-    shouldReserveSpaceForNavBar: Boolean = true,
     shouldIncludeHeadsUpSpace: Boolean = true,
     shouldShowScrim: Boolean = true,
     supportNestedScrolling: Boolean,
@@ -307,10 +308,7 @@
     val expansionFraction by viewModel.expandFraction.collectAsStateWithLifecycle(0f)
     val shadeToQsFraction by viewModel.shadeToQsFraction.collectAsStateWithLifecycle(0f)
 
-    val topPadding = dimensionResource(id = R.dimen.notification_side_paddings)
     val navBarHeight = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
-    val bottomPadding = if (shouldReserveSpaceForNavBar) navBarHeight else 0.dp
-
     val screenHeight = with(density) { LocalConfiguration.current.screenHeightDp.dp.toPx() }
 
     /**
@@ -340,11 +338,12 @@
     // set the bounds to null when the scrim disappears
     DisposableEffect(Unit) { onDispose { viewModel.onScrimBoundsChanged(null) } }
 
-    val minScrimTop = with(density) { ShadeHeader.Dimensions.CollapsedHeight.toPx() }
+    // Top position if the scrim, when it is fully expanded.
+    val minScrimTop = ShadeHeader.Dimensions.CollapsedHeight
 
     // The minimum offset for the scrim. The scrim is considered fully expanded when it
     // is at this offset.
-    val minScrimOffset: () -> Float = { minScrimTop - maxScrimTop() }
+    val minScrimOffset: () -> Float = { with(density) { minScrimTop.toPx() } - maxScrimTop() }
 
     // The height of the scrim visible on screen when it is in its resting (collapsed) state.
     val minVisibleScrimHeight: () -> Float = {
@@ -362,8 +361,9 @@
     val shadeScrollState by remember {
         derivedStateOf {
             ShadeScrollState(
-                // we are not scrolled to the top unless the scrim is at its maximum offset.
-                isScrolledToTop = scrimOffset.value >= 0f,
+                // we are not scrolled to the top unless the scroll position is zero,
+                // and the scrim is at its maximum offset
+                isScrolledToTop = scrimOffset.value >= 0f && scrollState.value == 0,
                 scrollPosition = scrollState.value,
                 maxScrollPosition = scrollState.maxValue,
             )
@@ -563,6 +563,7 @@
                     }
                     .thenIf(shouldShowScrim) { Modifier.background(scrimBackgroundColor) }
                     .thenIf(shouldFillMaxSize) { Modifier.fillMaxSize() }
+                    .thenIf(supportNestedScrolling) { Modifier.padding(bottom = minScrimTop) }
                     .debugBackground(viewModel, DEBUG_BOX_COLOR)
         ) {
             Column(
@@ -572,7 +573,7 @@
                         }
                         .stackVerticalOverscroll(coroutineScope) { scrollState.canScrollForward }
                         .verticalScroll(scrollState)
-                        .padding(top = topPadding)
+                        .padding(top = stackTopPadding, bottom = stackBottomPadding)
                         .fillMaxWidth()
                         .onGloballyPositioned { coordinates ->
                             stackBoundsOnScreen.value = coordinates.boundsInWindow()
@@ -585,11 +586,10 @@
                         !shouldUseLockscreenStackBounds(layoutState.transitionState)
                     },
                     modifier =
-                        Modifier.notificationStackHeight(
-                                view = stackScrollView,
-                                totalVerticalPadding = topPadding + bottomPadding,
-                            )
-                            .onSizeChanged { size -> stackHeight.intValue = size.height },
+                        Modifier.notificationStackHeight(view = stackScrollView).onSizeChanged {
+                            size ->
+                            stackHeight.intValue = size.height
+                        },
                 )
                 Spacer(
                     modifier =
@@ -605,7 +605,7 @@
                 stackScrollView = stackScrollView,
                 viewModel = viewModel,
                 useHunBounds = { !shouldUseLockscreenHunBounds(layoutState.transitionState) },
-                modifier = Modifier.padding(top = topPadding),
+                modifier = Modifier.padding(top = stackTopPadding),
             )
         }
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
index 5790c4a..9eb1f68 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt
@@ -16,12 +16,15 @@
 
 package com.android.systemui.notifications.ui.composable
 
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.layout.layoutId
+import androidx.compose.ui.res.dimensionResource
 import com.android.compose.animation.scene.ContentScope
 import com.android.compose.animation.scene.ElementKey
 import com.android.compose.animation.scene.UserAction
@@ -34,6 +37,7 @@
 import com.android.systemui.lifecycle.rememberViewModel
 import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayActionsViewModel
 import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeOverlayContentViewModel
+import com.android.systemui.res.R
 import com.android.systemui.scene.session.ui.composable.SaveableSession
 import com.android.systemui.scene.shared.model.Overlays
 import com.android.systemui.scene.ui.composable.Overlay
@@ -61,7 +65,6 @@
     private val clockSection: DefaultClockSection,
     private val clockInteractor: KeyguardClockInteractor,
 ) : Overlay {
-
     override val key = Overlays.NotificationsShade
 
     private val actionsViewModel: NotificationsShadeOverlayActionsViewModel by lazy {
@@ -76,6 +79,9 @@
 
     @Composable
     override fun ContentScope.Content(modifier: Modifier) {
+
+        val notificationStackPadding = dimensionResource(id = R.dimen.notification_side_paddings)
+
         val viewModel =
             rememberViewModel("NotificationsShadeOverlay-viewModel") {
                 contentViewModelFactory.create()
@@ -90,47 +96,52 @@
             modifier = modifier,
             onScrimClicked = viewModel::onScrimClicked,
         ) {
-            Column {
-                if (viewModel.showHeader) {
-                    val burnIn = rememberBurnIn(clockInteractor)
+            Box {
+                Column {
+                    if (viewModel.showHeader) {
+                        val burnIn = rememberBurnIn(clockInteractor)
 
-                    CollapsedShadeHeader(
-                        viewModelFactory = viewModel.shadeHeaderViewModelFactory,
-                        createTintedIconManager = tintedIconManagerFactory::create,
-                        createBatteryMeterViewController =
-                            batteryMeterViewControllerFactory::create,
-                        statusBarIconController = statusBarIconController,
-                        modifier =
-                            Modifier.element(NotificationsShade.Elements.StatusBar)
-                                .layoutId(SingleShadeMeasurePolicy.LayoutId.ShadeHeader),
-                    )
-
-                    with(clockSection) {
-                        SmallClock(
-                            burnInParams = burnIn.parameters,
-                            onTopChanged = burnIn.onSmallClockTopChanged,
-                            modifier = Modifier.fillMaxWidth(),
+                        CollapsedShadeHeader(
+                            viewModelFactory = viewModel.shadeHeaderViewModelFactory,
+                            createTintedIconManager = tintedIconManagerFactory::create,
+                            createBatteryMeterViewController =
+                                batteryMeterViewControllerFactory::create,
+                            statusBarIconController = statusBarIconController,
+                            modifier =
+                                Modifier.element(NotificationsShade.Elements.StatusBar)
+                                    .layoutId(SingleShadeMeasurePolicy.LayoutId.ShadeHeader),
                         )
+
+                        with(clockSection) {
+                            SmallClock(
+                                burnInParams = burnIn.parameters,
+                                onTopChanged = burnIn.onSmallClockTopChanged,
+                                modifier = Modifier.fillMaxWidth(),
+                            )
+                        }
                     }
+
+                    NotificationScrollingStack(
+                        shadeSession = shadeSession,
+                        stackScrollView = stackScrollView.get(),
+                        viewModel = placeholderViewModel,
+                        maxScrimTop = { 0f },
+                        stackTopPadding = notificationStackPadding,
+                        stackBottomPadding = notificationStackPadding,
+                        shouldPunchHoleBehindScrim = false,
+                        shouldFillMaxSize = false,
+                        shouldShowScrim = false,
+                        supportNestedScrolling = false,
+                        modifier = Modifier.fillMaxWidth(),
+                    )
                 }
-
-                NotificationScrollingStack(
-                    shadeSession = shadeSession,
-                    stackScrollView = stackScrollView.get(),
-                    viewModel = placeholderViewModel,
-                    maxScrimTop = { 0f },
-                    shouldPunchHoleBehindScrim = false,
-                    shouldFillMaxSize = false,
-                    shouldReserveSpaceForNavBar = false,
-                    shouldShowScrim = false,
-                    supportNestedScrolling = false,
-                    modifier = Modifier.fillMaxWidth(),
-                )
-
                 // Communicates the bottom position of the drawable area within the shade to NSSL.
                 NotificationStackCutoffGuideline(
                     stackScrollView = stackScrollView.get(),
                     viewModel = placeholderViewModel,
+                    modifier =
+                        Modifier.align(Alignment.BottomCenter)
+                            .padding(bottom = notificationStackPadding),
                 )
             }
         }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
index 52adaf2..26cf706 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -74,7 +74,6 @@
 import com.android.compose.animation.scene.animateSceneDpAsState
 import com.android.compose.animation.scene.animateSceneFloatAsState
 import com.android.compose.animation.scene.content.state.TransitionState
-import com.android.compose.modifiers.padding
 import com.android.compose.modifiers.thenIf
 import com.android.compose.windowsizeclass.LocalWindowSizeClass
 import com.android.systemui.battery.BatteryMeterViewController
@@ -433,12 +432,15 @@
         // A 1 pixel is added to compensate for any kind of rounding errors to make sure 100% that
         // the notification stack is entirely "below" the entire screen.
         val minNotificationStackTop = screenHeight.roundToInt() + 1
+        val notificationStackPadding = dimensionResource(id = R.dimen.notification_side_paddings)
         NotificationScrollingStack(
             shadeSession = shadeSession,
             stackScrollView = notificationStackScrollView,
             viewModel = notificationsPlaceholderViewModel,
             maxScrimTop = { minNotificationStackTop.toFloat() },
             shouldPunchHoleBehindScrim = shouldPunchHoleBehindScrim,
+            stackTopPadding = notificationStackPadding,
+            stackBottomPadding = navBarBottomHeight,
             shouldIncludeHeadsUpSpace = false,
             supportNestedScrolling = true,
             modifier =
@@ -453,7 +455,12 @@
                 Modifier.align(Alignment.BottomCenter)
                     .navigationBarsPadding()
                     .offset { IntOffset(x = 0, y = minNotificationStackTop) }
-                    .padding(horizontal = shadeHorizontalPadding),
+                    .padding(
+                        start = shadeHorizontalPadding,
+                        top = 0.dp,
+                        end = shadeHorizontalPadding,
+                        bottom = navBarBottomHeight,
+                    ),
         )
     }
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
index 3327fc0..f052e60 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
@@ -103,12 +103,15 @@
             onScrimClicked = viewModel::onScrimClicked,
         ) {
             Column {
-                CollapsedShadeHeader(
-                    viewModelFactory = viewModel.shadeHeaderViewModelFactory,
-                    createTintedIconManager = tintedIconManagerFactory::create,
-                    createBatteryMeterViewController = batteryMeterViewControllerFactory::create,
-                    statusBarIconController = statusBarIconController,
-                )
+                if (viewModel.showHeader) {
+                    CollapsedShadeHeader(
+                        viewModelFactory = viewModel.shadeHeaderViewModelFactory,
+                        createTintedIconManager = tintedIconManagerFactory::create,
+                        createBatteryMeterViewController =
+                            batteryMeterViewControllerFactory::create,
+                        statusBarIconController = statusBarIconController,
+                    )
+                }
 
                 ShadeBody(viewModel = viewModel.quickSettingsContainerViewModel)
             }
@@ -178,8 +181,8 @@
     Column(
         verticalArrangement = Arrangement.spacedBy(QuickSettingsShade.Dimensions.Padding),
         horizontalAlignment = Alignment.CenterHorizontally,
-        modifier = modifier
-            .padding(
+        modifier =
+            modifier.padding(
                 start = QuickSettingsShade.Dimensions.Padding,
                 end = QuickSettingsShade.Dimensions.Padding,
                 bottom = QuickSettingsShade.Dimensions.Padding,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index a53c6b2..0d3bab2 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -36,7 +36,6 @@
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.navigationBars
-import androidx.compose.foundation.layout.navigationBarsPadding
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.systemBars
 import androidx.compose.foundation.overscroll
@@ -76,7 +75,6 @@
 import com.android.systemui.battery.BatteryMeterViewController
 import com.android.systemui.common.ui.compose.windowinsets.CutoutLocation
 import com.android.systemui.common.ui.compose.windowinsets.LocalDisplayCutout
-import com.android.systemui.common.ui.compose.windowinsets.LocalScreenCornerRadius
 import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.lifecycle.ExclusiveActivatable
@@ -239,7 +237,7 @@
                 modifier = modifier,
                 shadeSession = shadeSession,
             )
-        is ShadeMode.Dual -> error("Dual shade is not yet implemented!")
+        is ShadeMode.Dual -> error("Dual shade is implemented separately as an overlay.")
     }
 }
 
@@ -283,7 +281,7 @@
             key = MediaLandscapeTopOffset,
             canOverflow = false,
         )
-
+    val notificationStackPadding = dimensionResource(id = R.dimen.notification_side_paddings)
     val navBarHeight = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
 
     val mediaOffsetProvider = remember {
@@ -383,6 +381,8 @@
                     viewModel = notificationsPlaceholderViewModel,
                     maxScrimTop = { maxNotifScrimTop.toFloat() },
                     shouldPunchHoleBehindScrim = shouldPunchHoleBehindScrim,
+                    stackTopPadding = notificationStackPadding,
+                    stackBottomPadding = navBarHeight,
                     supportNestedScrolling = true,
                     onEmptySpaceClick =
                         viewModel::onEmptySpaceClicked.takeIf { isEmptySpaceClickable },
@@ -422,8 +422,6 @@
     modifier: Modifier = Modifier,
     shadeSession: SaveableSession,
 ) {
-    val screenCornerRadius = LocalScreenCornerRadius.current
-
     val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsStateWithLifecycle()
     val isQsEnabled by viewModel.isQsEnabled.collectAsStateWithLifecycle()
     val isCustomizerShowing by
@@ -444,6 +442,7 @@
     val unfoldTranslationXForEndSide by
         viewModel.unfoldTranslationX(isOnStartSide = false).collectAsStateWithLifecycle(0f)
 
+    val notificationStackPadding = dimensionResource(id = R.dimen.notification_side_paddings)
     val navBarBottomHeight = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()
     val bottomPadding by
         animateDpAsState(
@@ -604,8 +603,9 @@
                     stackScrollView = notificationStackScrollView,
                     viewModel = notificationsPlaceholderViewModel,
                     maxScrimTop = { 0f },
+                    stackTopPadding = notificationStackPadding,
+                    stackBottomPadding = notificationStackPadding,
                     shouldPunchHoleBehindScrim = false,
-                    shouldReserveSpaceForNavBar = false,
                     supportNestedScrolling = false,
                     onEmptySpaceClick =
                         viewModel::onEmptySpaceClicked.takeIf { isEmptySpaceClickable },
@@ -624,7 +624,9 @@
         NotificationStackCutoffGuideline(
             stackScrollView = notificationStackScrollView,
             viewModel = notificationsPlaceholderViewModel,
-            modifier = Modifier.align(Alignment.BottomCenter).navigationBarsPadding(),
+            modifier =
+                Modifier.align(Alignment.BottomCenter)
+                    .padding(bottom = notificationStackPadding + navBarBottomHeight),
         )
     }
 }
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
index 8777ff9..495fdaf 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
@@ -434,7 +434,8 @@
             if (element != null) {
                 layoutImpl.elements[element]?.let { element ->
                     elementState(
-                        layoutImpl.state.transitionStates,
+                        listOf(layoutImpl.state.transitionStates),
+                        elementKey = element.key,
                         isInContent = { it in element.stateByContent },
                     )
                         as? TransitionState.Transition
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
index 16b4322..8865a07 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
@@ -45,7 +45,11 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.round
+import androidx.compose.ui.util.fastAll
+import androidx.compose.ui.util.fastAny
 import androidx.compose.ui.util.fastCoerceIn
+import androidx.compose.ui.util.fastForEach
+import androidx.compose.ui.util.fastForEachIndexed
 import androidx.compose.ui.util.fastForEachReversed
 import androidx.compose.ui.util.lerp
 import com.android.compose.animation.scene.content.Content
@@ -92,7 +96,17 @@
 
     /** The last and target state of this element in a given content. */
     @Stable
-    class State(val content: ContentKey) {
+    class State(
+        /**
+         * A list of contents where this element state finds itself in. The last content is the
+         * content of the STL which is actually responsible to compose and place this element. The
+         * other contents (if any) are the ancestors. The ancestors do not actually place this
+         * element but the element is part of the ancestors scene as part of a NestedSTL. The state
+         * can be accessed by ancestor transitions to read the properties of this element to compute
+         * transformations.
+         */
+        val contents: List<ContentKey>
+    ) {
         /**
          * The *target* state of this element in this content, i.e. the state of this element when
          * we are idle on this content.
@@ -158,7 +172,8 @@
     // layout/drawing.
     // TODO(b/341072461): Revert this and read the current transitions in ElementNode directly once
     // we can ensure that SceneTransitionLayoutImpl will compose new contents first.
-    val currentTransitionStates = layoutImpl.state.transitionStates
+    val currentTransitionStates = getAllNestedTransitionStates(layoutImpl)
+
     return thenIf(layoutImpl.state.isElevationPossible(content.key, key)) {
             Modifier.maybeElevateInContent(layoutImpl, content, key, currentTransitionStates)
         }
@@ -166,11 +181,26 @@
         .testTag(key.testTag)
 }
 
+/**
+ * Returns the transition states of all ancestors + the transition state of the current STL. The
+ * last element is the transition state of the local STL (the one with the highest nestingDepth).
+ *
+ * @return Each transition state of a STL is a List and this is a list of all the states.
+ */
+internal fun getAllNestedTransitionStates(
+    layoutImpl: SceneTransitionLayoutImpl
+): List<List<TransitionState>> {
+    return buildList {
+        layoutImpl.ancestors.fastForEach { add(it.layoutImpl.state.transitionStates) }
+        add(layoutImpl.state.transitionStates)
+    }
+}
+
 private fun Modifier.maybeElevateInContent(
     layoutImpl: SceneTransitionLayoutImpl,
     content: Content,
     key: ElementKey,
-    transitionStates: List<TransitionState>,
+    transitionStates: List<List<TransitionState>>,
 ): Modifier {
     fun isSharedElement(
         stateByContent: Map<ContentKey, Element.State>,
@@ -192,12 +222,12 @@
         content.containerState,
         enabled = {
             val stateByContent = layoutImpl.elements.getValue(key).stateByContent
-            val state = elementState(transitionStates, isInContent = { it in stateByContent })
+            val state = elementState(transitionStates, key, isInContent = { it in stateByContent })
 
             state is TransitionState.Transition &&
                 state.transformationSpec
                     .transformations(key, content.key)
-                    .shared
+                    ?.shared
                     ?.transformation
                     ?.elevateInContent == content.key &&
                 isSharedElement(stateByContent, state) &&
@@ -218,7 +248,7 @@
  */
 internal data class ElementModifier(
     internal val layoutImpl: SceneTransitionLayoutImpl,
-    private val currentTransitionStates: List<TransitionState>,
+    private val currentTransitionStates: List<List<TransitionState>>,
     internal val content: Content,
     internal val key: ElementKey,
 ) : ModifierNodeElement<ElementNode>() {
@@ -232,7 +262,7 @@
 
 internal class ElementNode(
     private var layoutImpl: SceneTransitionLayoutImpl,
-    private var currentTransitionStates: List<TransitionState>,
+    private var currentTransitionStates: List<List<TransitionState>>,
     private var content: Content,
     private var key: ElementKey,
 ) : Modifier.Node(), DrawModifierNode, ApproachLayoutModifierNode, TraversableNode {
@@ -257,10 +287,15 @@
         _element = element
         addToRenderAuthority(element)
         if (!element.stateByContent.contains(content.key)) {
-            val elementState = Element.State(content.key)
+            val contents = buildList {
+                layoutImpl.ancestors.fastForEach { add(it.inContent) }
+                add(content.key)
+            }
+
+            val elementState = Element.State(contents)
             element.stateByContent[content.key] = elementState
 
-            layoutImpl.ancestorContentKeys.forEach { element.stateByContent[it] = elementState }
+            layoutImpl.ancestors.fastForEach { element.stateByContent[it.inContent] = elementState }
         }
     }
 
@@ -273,7 +308,7 @@
             // this element was composed multiple times in the same content.
             val nCodeLocations = stateInContent.nodes.size
             if (nCodeLocations != 1 || !stateInContent.nodes.contains(this@ElementNode)) {
-                error("$key was composed $nCodeLocations times in ${stateInContent.content}")
+                error("$key was composed $nCodeLocations times in ${stateInContent.contents}")
             }
         }
     }
@@ -288,12 +323,12 @@
     }
 
     private fun addToRenderAuthority(element: Element) {
-        val nestingDepth = layoutImpl.ancestorContentKeys.size
+        val nestingDepth = layoutImpl.ancestors.size
         element.renderAuthority[nestingDepth] = content.key
     }
 
     private fun removeFromRenderAuthority() {
-        val nestingDepth = layoutImpl.ancestorContentKeys.size
+        val nestingDepth = layoutImpl.ancestors.size
         if (element.renderAuthority[nestingDepth] == content.key) {
             element.renderAuthority.remove(nestingDepth)
         }
@@ -305,7 +340,7 @@
 
     fun update(
         layoutImpl: SceneTransitionLayoutImpl,
-        currentTransitionStates: List<TransitionState>,
+        currentTransitionStates: List<List<TransitionState>>,
         content: Content,
         key: ElementKey,
     ) {
@@ -326,7 +361,7 @@
     override fun isMeasurementApproachInProgress(lookaheadSize: IntSize): Boolean {
         // TODO(b/324191441): Investigate whether making this check more complex (checking if this
         // element is shared or transformed) would lead to better performance.
-        return layoutImpl.state.isTransitioning()
+        return isAnyStateTransitioning()
     }
 
     override fun Placeable.PlacementScope.isPlacementApproachInProgress(
@@ -334,7 +369,12 @@
     ): Boolean {
         // TODO(b/324191441): Investigate whether making this check more complex (checking if this
         // element is shared or transformed) would lead to better performance.
-        return layoutImpl.state.isTransitioning()
+        return isAnyStateTransitioning()
+    }
+
+    private fun isAnyStateTransitioning(): Boolean {
+        return layoutImpl.state.isTransitioning() ||
+            layoutImpl.ancestors.fastAny { it.layoutImpl.state.isTransitioning() }
     }
 
     @ExperimentalComposeUiApi
@@ -372,7 +412,7 @@
             // This is the case if for example a transition between two overlays is ongoing where
             // sharedElement isn't part of either but the element is still rendered as part of
             // the underlying scene that is currently not being transitioned.
-            val currentState = currentTransitionStates.last()
+            val currentState = currentTransitionStates.last().last()
             val shouldPlaceInThisContent =
                 elementContentWhenIdle(
                     layoutImpl,
@@ -448,7 +488,7 @@
                     element,
                     transition,
                     contentValue = { it.targetOffset },
-                    transformation = { it.offset },
+                    transformation = { it?.offset },
                     currentValue = { currentOffset },
                     isSpecified = { it != Offset.Unspecified },
                     ::lerp,
@@ -592,8 +632,7 @@
                 }
             }
 
-            pruneForContent(stateInContent.content)
-            layoutImpl.ancestorContentKeys.forEach { content -> pruneForContent(content) }
+            stateInContent.contents.fastForEach { pruneForContent(it) }
         }
     }
 }
@@ -602,9 +641,10 @@
 private fun elementState(
     layoutImpl: SceneTransitionLayoutImpl,
     element: Element,
-    transitionStates: List<TransitionState>,
+    transitionStates: List<List<TransitionState>>,
 ): TransitionState? {
-    val state = elementState(transitionStates, isInContent = { it in element.stateByContent })
+    val state =
+        elementState(transitionStates, element.key, isInContent = { it in element.stateByContent })
 
     val transition = state as? TransitionState.Transition
     val previousTransition = element.lastTransition
@@ -625,23 +665,48 @@
 }
 
 internal inline fun elementState(
-    transitionStates: List<TransitionState>,
+    transitionStates: List<List<TransitionState>>,
+    elementKey: ElementKey,
     isInContent: (ContentKey) -> Boolean,
 ): TransitionState? {
-    val lastState = transitionStates.last()
-    if (lastState is TransitionState.Idle) {
-        check(transitionStates.size == 1)
-        return lastState
-    }
+    // transitionStates is a list of all ancestor transition states + transitionState of the local
+    // STL. By traversing the list in normal order we by default prioritize the transitionState of
+    // the highest ancestor if it is running and has a transformation for this element.
+    transitionStates.fastForEachIndexed { index, states ->
+        if (index < transitionStates.size - 1) {
+            // Check if any ancestor runs a transition that has a transformation for the element
+            states.fastForEachReversed { state ->
+                if (
+                    state is TransitionState.Transition &&
+                        (state.transformationSpec.hasTransformation(
+                            elementKey,
+                            state.fromContent,
+                        ) ||
+                            state.transformationSpec.hasTransformation(elementKey, state.toContent))
+                ) {
+                    return state
+                }
+            }
+        } else {
+            // the last state of the list, is the state of the local STL
+            val lastState = states.last()
+            if (lastState is TransitionState.Idle) {
+                check(states.size == 1)
+                return lastState
+            }
 
-    // Find the last transition with a content that contains the element.
-    transitionStates.fastForEachReversed { state ->
-        val transition = state as TransitionState.Transition
-        if (isInContent(transition.fromContent) || isInContent(transition.toContent)) {
-            return transition
+            // Find the last transition with a content that contains the element.
+            states.fastForEachReversed { state ->
+                val transition = state as TransitionState.Transition
+                if (isInContent(transition.fromContent) || isInContent(transition.toContent)) {
+                    return transition
+                }
+            }
         }
     }
-
+    // We are running a transition where both from and to don't contain the element. The element
+    // may still be rendered as e.g. it can be part of a idle scene where two overlays are currently
+    // transitioning above it.
     return null
 }
 
@@ -706,7 +771,7 @@
         stateInContent.alphaInterruptionDelta = 0f
         stateInContent.scaleInterruptionDelta = Scale.Zero
 
-        if (!shouldPlaceElement(layoutImpl, stateInContent.content, element, transition)) {
+        if (!shouldPlaceElement(layoutImpl, stateInContent.contents.last(), element, transition)) {
             stateInContent.offsetBeforeInterruption = Offset.Unspecified
             stateInContent.alphaBeforeInterruption = Element.AlphaUnspecified
             stateInContent.scaleBeforeInterruption = Scale.Unspecified
@@ -720,7 +785,7 @@
 }
 
 /**
- * Reconcile the state of [element] in the formContent and toContent of [transition] so that the
+ * Reconcile the state of [element] in the fromContent and toContent of [transition] so that the
  * values before interruption have their expected values, taking shared transitions into account.
  *
  * @return the unique state this element had during [transition], `null` if it had multiple
@@ -878,7 +943,7 @@
     // If the element is shared, also set the delta on the other content so that it is used by that
     // content if we start overscrolling it and change the content where the element is placed.
     val otherContent =
-        if (stateInContent.content == transition.fromContent) transition.toContent
+        if (stateInContent.contents.last() == transition.fromContent) transition.toContent
         else transition.fromContent
     val otherContentState = element.stateByContent[otherContent] ?: return
     if (isSharedElementEnabled(element.key, transition)) {
@@ -916,7 +981,8 @@
     if (
         content != transition.fromContent &&
             content != transition.toContent &&
-            (!isReplacingOverlay || content != transition.currentScene)
+            (!isReplacingOverlay || content != transition.currentScene) &&
+            transitionDoesNotInvolveAncestorContent(layoutImpl, transition)
     ) {
         return false
     }
@@ -938,6 +1004,15 @@
     return shouldPlaceSharedElement(layoutImpl, content, element.key, transition)
 }
 
+private fun transitionDoesNotInvolveAncestorContent(
+    layoutImpl: SceneTransitionLayoutImpl,
+    transition: TransitionState.Transition,
+): Boolean {
+    return layoutImpl.ancestors.fastAll {
+        it.inContent != transition.fromContent && it.inContent != transition.toContent
+    }
+}
+
 /**
  * Whether the element is opaque or not.
  *
@@ -968,7 +1043,7 @@
         return true
     }
 
-    return transition.transformationSpec.transformations(element.key, content.key).alpha == null
+    return transition.transformationSpec.transformations(element.key, content.key)?.alpha == null
 }
 
 /**
@@ -992,7 +1067,7 @@
                 element,
                 transition,
                 contentValue = { 1f },
-                transformation = { it.alpha },
+                transformation = { it?.alpha },
                 currentValue = { 1f },
                 isSpecified = { true },
                 ::lerp,
@@ -1060,7 +1135,7 @@
             element,
             transition,
             contentValue = { it.targetSize },
-            transformation = { it.size },
+            transformation = { it?.size },
             currentValue = { measurable.measure(constraints).also { maybePlaceable = it }.size() },
             isSpecified = { it != Element.SizeUnspecified },
             ::lerp,
@@ -1093,7 +1168,6 @@
                 )
             },
         )
-
     return measurable.measure(
         Constraints.fixed(
             interruptedSize.width.coerceAtLeast(0),
@@ -1117,7 +1191,7 @@
             element,
             transition,
             contentValue = { Scale.Default },
-            transformation = { it.drawScale },
+            transformation = { it?.drawScale },
             currentValue = { Scale.Default },
             isSpecified = { true },
             ::lerp,
@@ -1205,7 +1279,8 @@
     element: Element,
     transition: TransitionState.Transition?,
     contentValue: (Element.State) -> T,
-    transformation: (ElementTransformations) -> TransformationWithRange<PropertyTransformation<T>>?,
+    transformation:
+        (ElementTransformations?) -> TransformationWithRange<PropertyTransformation<T>>?,
     currentValue: () -> T,
     isSpecified: (T) -> Boolean,
     lerp: (T, T, Float) -> T,
@@ -1230,10 +1305,9 @@
         return contentValue(currentContentState)
     }
 
-    val currentContent = currentContentState.content
+    val currentContent = currentContentState.contents.last()
 
-    // The element is shared: interpolate between the value in fromContent and the value in
-    // toContent.
+    // The element is shared: interpolate between the value in fromContent and toContent.
     // TODO(b/290184746): Support non linear shared paths as well as a way to make sure that shared
     // elements follow the finger direction.
     val isSharedElement = fromState != null && toState != null
@@ -1265,127 +1339,55 @@
         }
     }
 
-    // Get the transformed value, i.e. the target value at the beginning (for entering elements) or
-    // end (for leaving elements) of the transition.
-    val contentState =
-        checkNotNull(
-            when {
-                isSharedElement && currentContent == fromContent -> fromState
-                isSharedElement -> toState
-                currentSceneState != null && currentContent == transition.currentScene ->
-                    currentSceneState
-                else -> fromState ?: toState
-            }
-        )
-
     // The content for which we compute the transformation. Note that this is not necessarily
     // [currentContent] because [currentContent] could be a different content than the transition
-    // fromContent or toContent during interruptions.
-    val content = contentState.content
+    // fromContent or toContent during interruptions or when a ancestor transition is running.
+    val transformationContentKey: ContentKey =
+        getTransformationContentKey(
+            isDisabledSharedElement = isSharedElement,
+            currentContent = currentContent,
+            layoutImpl = layoutImpl,
+            transition = transition,
+            element = element,
+            currentSceneState = currentSceneState,
+        )
+    // Get the transformed value, i.e. the target value at the beginning (for entering elements) or
+    // end (for leaving elements) of the transition.
+    val targetState: Element.State = element.stateByContent.getValue(transformationContentKey)
+    val idleValue = contentValue(targetState)
 
     val transformationWithRange =
-        transformation(transition.transformationSpec.transformations(element.key, content))
+        transformation(
+            transition.transformationSpec.transformations(element.key, transformationContentKey)
+        )
+
+    val isElementEntering =
+        when {
+            transformationContentKey == toContent -> true
+            transformationContentKey == fromContent -> false
+            isAncestorTransition(layoutImpl, transition) ->
+                isEnteringAncestorTransition(layoutImpl, transition)
+            transformationContentKey == transition.currentScene -> toState == null
+            else -> transformationContentKey == toContent
+        }
 
     val previewTransformation =
         transition.previewTransformationSpec?.let {
-            transformation(it.transformations(element.key, content))
+            transformation(it.transformations(element.key, transformationContentKey))
         }
+
     if (previewTransformation != null) {
-        val isInPreviewStage = transition.isInPreviewStage
-
-        val idleValue = contentValue(contentState)
-        val isEntering = content == toContent
-        val previewTargetValue =
-            with(
-                previewTransformation.transformation.requireInterpolatedTransformation(
-                    element,
-                    transition,
-                ) {
-                    "Custom transformations in preview specs should not be possible"
-                }
-            ) {
-                layoutImpl.propertyTransformationScope.transform(
-                    content,
-                    element.key,
-                    transition,
-                    idleValue,
-                )
-            }
-
-        val targetValueOrNull =
-            transformationWithRange?.let { transformation ->
-                with(
-                    transformation.transformation.requireInterpolatedTransformation(
-                        element,
-                        transition,
-                    ) {
-                        "Custom transformations are not allowed for properties with a preview"
-                    }
-                ) {
-                    layoutImpl.propertyTransformationScope.transform(
-                        content,
-                        element.key,
-                        transition,
-                        idleValue,
-                    )
-                }
-            }
-
-        // Make sure we don't read progress if values are the same and we don't need to interpolate,
-        // so we don't invalidate the phase where this is read.
-        when {
-            isInPreviewStage && isEntering && previewTargetValue == targetValueOrNull ->
-                return previewTargetValue
-            isInPreviewStage && !isEntering && idleValue == previewTargetValue -> return idleValue
-            previewTargetValue == targetValueOrNull && idleValue == previewTargetValue ->
-                return idleValue
-            else -> {}
-        }
-
-        val previewProgress = transition.previewProgress
-        // progress is not needed for all cases of the below when block, therefore read it lazily
-        // TODO(b/290184746): Make sure that we don't overflow transformations associated to a range
-        val previewRangeProgress =
-            previewTransformation.range?.progress(previewProgress) ?: previewProgress
-
-        if (isInPreviewStage) {
-            // if we're in the preview stage of the transition, interpolate between start state and
-            // preview target state:
-            return if (isEntering) {
-                // i.e. in the entering case between previewTargetValue and targetValue (or
-                // idleValue if no transformation is defined in the second stage transition)...
-                lerp(previewTargetValue, targetValueOrNull ?: idleValue, previewRangeProgress)
-            } else {
-                // ...and in the exiting case between the idleValue and the previewTargetValue.
-                lerp(idleValue, previewTargetValue, previewRangeProgress)
-            }
-        }
-
-        // if we're in the second stage of the transition, interpolate between the state the
-        // element was left at the end of the preview-phase and the target state:
-        return if (isEntering) {
-            // i.e. in the entering case between preview-end-state and the idleValue...
-            lerp(
-                lerp(previewTargetValue, targetValueOrNull ?: idleValue, previewRangeProgress),
-                idleValue,
-                transformationWithRange?.range?.progress(transition.progress) ?: transition.progress,
-            )
-        } else {
-            if (targetValueOrNull == null) {
-                // ... and in the exiting case, the element should remain in the preview-end-state
-                // if no further transformation is defined in the second-stage transition...
-                lerp(idleValue, previewTargetValue, previewRangeProgress)
-            } else {
-                // ...and otherwise it should be interpolated between preview-end-state and
-                // targetValue
-                lerp(
-                    lerp(idleValue, previewTargetValue, previewRangeProgress),
-                    targetValueOrNull,
-                    transformationWithRange.range?.progress(transition.progress)
-                        ?: transition.progress,
-                )
-            }
-        }
+        return computePreviewTransformationValue(
+            transition,
+            idleValue,
+            transformationContentKey,
+            isElementEntering,
+            previewTransformation,
+            element,
+            layoutImpl,
+            transformationWithRange,
+            lerp,
+        )
     }
 
     if (transformationWithRange == null) {
@@ -1400,7 +1402,7 @@
         is CustomPropertyTransformation ->
             return with(transformation) {
                 layoutImpl.propertyTransformationScope.transform(
-                    content,
+                    transformationContentKey,
                     element.key,
                     transition,
                     transition.coroutineScope,
@@ -1411,11 +1413,10 @@
         }
     }
 
-    val idleValue = contentValue(contentState)
     val targetValue =
         with(transformation) {
             layoutImpl.propertyTransformationScope.transform(
-                content,
+                transformationContentKey,
                 element.key,
                 transition,
                 idleValue,
@@ -1432,21 +1433,183 @@
     // TODO(b/290184746): Make sure that we don't overflow transformations associated to a range.
     val rangeProgress = transformationWithRange.range?.progress(progress) ?: progress
 
-    // Interpolate between the value at rest and the value before entering/after leaving.
-    val isEntering =
-        when {
-            content == toContent -> true
-            content == fromContent -> false
-            content == transition.currentScene -> toState == null
-            else -> content == toContent
-        }
-    return if (isEntering) {
+    return if (isElementEntering) {
         lerp(targetValue, idleValue, rangeProgress)
     } else {
         lerp(idleValue, targetValue, rangeProgress)
     }
 }
 
+private fun getTransformationContentKey(
+    isDisabledSharedElement: Boolean,
+    currentContent: ContentKey,
+    layoutImpl: SceneTransitionLayoutImpl,
+    transition: TransitionState.Transition,
+    element: Element,
+    currentSceneState: Element.State?,
+): ContentKey {
+    return when {
+        isDisabledSharedElement -> {
+            currentContent
+        }
+        isAncestorTransition(layoutImpl, transition) -> {
+            if (
+                element.stateByContent[transition.fromContent] != null &&
+                    transition.transformationSpec.hasTransformation(
+                        element.key,
+                        transition.fromContent,
+                    )
+            ) {
+                transition.fromContent
+            } else if (
+                element.stateByContent[transition.toContent] != null &&
+                    transition.transformationSpec.hasTransformation(
+                        element.key,
+                        transition.toContent,
+                    )
+            ) {
+                transition.toContent
+            } else {
+                throw IllegalStateException(
+                    "Ancestor transition is active but no transformation " +
+                        "spec was found. The ancestor transition should have only been selected " +
+                        "when a transformation for that element and content was defined."
+                )
+            }
+        }
+        currentSceneState != null && currentContent == transition.currentScene -> {
+            currentContent
+        }
+        element.stateByContent[transition.fromContent] != null -> {
+            transition.fromContent
+        }
+        else -> {
+            transition.toContent
+        }
+    }
+}
+
+private inline fun <T> computePreviewTransformationValue(
+    transition: TransitionState.Transition,
+    idleValue: T,
+    transformationContentKey: ContentKey,
+    isEntering: Boolean,
+    previewTransformation: TransformationWithRange<PropertyTransformation<T>>,
+    element: Element,
+    layoutImpl: SceneTransitionLayoutImpl,
+    transformationWithRange: TransformationWithRange<PropertyTransformation<T>>?,
+    lerp: (T, T, Float) -> T,
+): T {
+    val isInPreviewStage = transition.isInPreviewStage
+
+    val previewTargetValue =
+        with(
+            previewTransformation.transformation.requireInterpolatedTransformation(
+                element,
+                transition,
+            ) {
+                "Custom transformations in preview specs should not be possible"
+            }
+        ) {
+            layoutImpl.propertyTransformationScope.transform(
+                transformationContentKey,
+                element.key,
+                transition,
+                idleValue,
+            )
+        }
+
+    val targetValueOrNull =
+        transformationWithRange?.let { transformation ->
+            with(
+                transformation.transformation.requireInterpolatedTransformation(
+                    element,
+                    transition,
+                ) {
+                    "Custom transformations are not allowed for properties with a preview"
+                }
+            ) {
+                layoutImpl.propertyTransformationScope.transform(
+                    transformationContentKey,
+                    element.key,
+                    transition,
+                    idleValue,
+                )
+            }
+        }
+
+    // Make sure we don't read progress if values are the same and we don't need to interpolate,
+    // so we don't invalidate the phase where this is read.
+    when {
+        isInPreviewStage && isEntering && previewTargetValue == targetValueOrNull ->
+            return previewTargetValue
+        isInPreviewStage && !isEntering && idleValue == previewTargetValue -> return idleValue
+        previewTargetValue == targetValueOrNull && idleValue == previewTargetValue ->
+            return idleValue
+        else -> {}
+    }
+
+    val previewProgress = transition.previewProgress
+    // progress is not needed for all cases of the below when block, therefore read it lazily
+    // TODO(b/290184746): Make sure that we don't overflow transformations associated to a range
+    val previewRangeProgress =
+        previewTransformation.range?.progress(previewProgress) ?: previewProgress
+
+    if (isInPreviewStage) {
+        // if we're in the preview stage of the transition, interpolate between start state and
+        // preview target state:
+        return if (isEntering) {
+            // i.e. in the entering case between previewTargetValue and targetValue (or
+            // idleValue if no transformation is defined in the second stage transition)...
+            lerp(previewTargetValue, targetValueOrNull ?: idleValue, previewRangeProgress)
+        } else {
+            // ...and in the exiting case between the idleValue and the previewTargetValue.
+            lerp(idleValue, previewTargetValue, previewRangeProgress)
+        }
+    }
+
+    // if we're in the second stage of the transition, interpolate between the state the
+    // element was left at the end of the preview-phase and the target state:
+    return if (isEntering) {
+        // i.e. in the entering case between preview-end-state and the idleValue...
+        lerp(
+            lerp(previewTargetValue, targetValueOrNull ?: idleValue, previewRangeProgress),
+            idleValue,
+            transformationWithRange?.range?.progress(transition.progress) ?: transition.progress,
+        )
+    } else {
+        if (targetValueOrNull == null) {
+            // ... and in the exiting case, the element should remain in the preview-end-state
+            // if no further transformation is defined in the second-stage transition...
+            lerp(idleValue, previewTargetValue, previewRangeProgress)
+        } else {
+            // ...and otherwise it should be interpolated between preview-end-state and
+            // targetValue
+            lerp(
+                lerp(idleValue, previewTargetValue, previewRangeProgress),
+                targetValueOrNull,
+                transformationWithRange.range?.progress(transition.progress) ?: transition.progress,
+            )
+        }
+    }
+}
+
+private fun isAncestorTransition(
+    layoutImpl: SceneTransitionLayoutImpl,
+    transition: TransitionState.Transition,
+): Boolean {
+    return layoutImpl.ancestors.fastAny {
+        it.inContent == transition.fromContent || it.inContent == transition.toContent
+    }
+}
+
+private fun isEnteringAncestorTransition(
+    layoutImpl: SceneTransitionLayoutImpl,
+    transition: TransitionState.Transition,
+): Boolean {
+    return layoutImpl.ancestors.fastAny { it.inContent == transition.toContent }
+}
+
 private inline fun <T> PropertyTransformation<T>.requireInterpolatedTransformation(
     element: Element,
     transition: TransitionState.Transition,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
index 388456e..c10a485 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
@@ -163,7 +163,7 @@
             // Important: Like in Modifier.element(), we read the transition states during
             // composition then pass them to Layout to make sure that composition sees new states
             // before layout and drawing.
-            val transitionStates = layoutImpl.state.transitionStates
+            val transitionStates = getAllNestedTransitionStates(layoutImpl)
             Layout { _, _ ->
                 // No need to measure or place anything.
                 val size =
@@ -186,7 +186,7 @@
     element: MovableElementKey,
 ): Boolean {
     return when (
-        val elementState = movableElementState(element, layoutImpl.state.transitionStates)
+        val elementState = movableElementState(element, getAllNestedTransitionStates(layoutImpl))
     ) {
         null ->
             movableElementContentWhenIdle(layoutImpl, element, layoutImpl.state.transitionState) ==
@@ -221,10 +221,14 @@
 
 private fun movableElementState(
     element: MovableElementKey,
-    transitionStates: List<TransitionState>,
+    transitionStates: List<List<TransitionState>>,
 ): TransitionState? {
     val contents = element.contentPicker.contents
-    return elementState(transitionStates, isInContent = { contents.contains(it) })
+    return elementState(
+        transitionStates,
+        elementKey = element,
+        isInContent = { contents.contains(it) },
+    )
 }
 
 private fun movableElementContentWhenIdle(
@@ -245,7 +249,7 @@
     content: ContentKey,
     element: Element,
     elementKey: MovableElementKey,
-    transitionStates: List<TransitionState>,
+    transitionStates: List<List<TransitionState>>,
 ): IntSize {
     // If the content of the movable element was already composed in this scene before, use that
     // target size.
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index ce385ab..7b30a2a 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -698,7 +698,7 @@
     transitionInterceptionThreshold: Float = 0f,
     onLayoutImpl: ((SceneTransitionLayoutImpl) -> Unit)? = null,
     sharedElementMap: MutableMap<ElementKey, Element> = remember { mutableMapOf() },
-    ancestorContentKeys: List<ContentKey> = emptyList(),
+    ancestors: List<Ancestor> = remember { emptyList() },
     lookaheadScope: LookaheadScope? = null,
     builder: SceneTransitionLayoutScope.() -> Unit,
 ) {
@@ -715,7 +715,7 @@
                 builder = builder,
                 animationScope = animationScope,
                 elements = sharedElementMap,
-                ancestorContentKeys = ancestorContentKeys,
+                ancestors = ancestors,
                 lookaheadScope = lookaheadScope,
             )
             .also { onLayoutImpl?.invoke(it) }
@@ -738,9 +738,9 @@
                     "when creating it, which is not supported"
             )
         }
-        if (layoutImpl.ancestorContentKeys != ancestorContentKeys) {
+        if (layoutImpl.ancestors != ancestors) {
             error(
-                "This SceneTransitionLayout was bound to a different ancestorContents that was " +
+                "This SceneTransitionLayout was bound to a different ancestors that was " +
                     "used when creating it, which is not supported"
             )
         }
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
index e1cecc7..e5bdc92 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
@@ -57,6 +57,18 @@
 /** The type for the content of movable elements. */
 internal typealias MovableElementContent = @Composable (@Composable () -> Unit) -> Unit
 
+internal data class Ancestor(
+    val layoutImpl: SceneTransitionLayoutImpl,
+
+    /**
+     * This is the content in which the corresponding descendant of this ancestor appears in.
+     *
+     * Example: When A is the root and has two scenes SA and SB and SB contains a NestedSTL called
+     * B. Then A is the ancestor of B and inContent is SB.
+     */
+    val inContent: ContentKey,
+)
+
 @Stable
 internal class SceneTransitionLayoutImpl(
     internal val state: MutableSceneTransitionLayoutStateImpl,
@@ -83,16 +95,17 @@
     internal val elements: MutableMap<ElementKey, Element> = mutableMapOf(),
 
     /**
-     * When this STL is a [NestedSceneTransitionLayout], this is a list of [ContentKey]s of where
-     * this STL is composed in within its ancestors.
+     * When this STL is a [NestedSceneTransitionLayout], this is a list of [Ancestor]s which
+     * provides a reference to the ancestor STLs and indicates where this STL is composed in within
+     * its ancestors.
      *
      * The root STL holds an emptyList. With each nesting level the parent is supposed to add
      * exactly one scene to the list, therefore the size of this list is equal to the nesting depth
      * of this STL.
      *
-     * This is used to know in which content of the ancestors a sharedElement appears in.
+     * This is used to enable transformations and shared elements across NestedSTLs.
      */
-    internal val ancestorContentKeys: List<ContentKey> = emptyList(),
+    internal val ancestors: List<Ancestor> = emptyList(),
     lookaheadScope: LookaheadScope? = null,
 ) {
 
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt
index 6479e69..756d71c 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt
@@ -266,19 +266,26 @@
     override val distance: UserActionDistance?,
     override val transformationMatchers: List<TransformationMatcher>,
 ) : TransformationSpec {
-    private val cache = mutableMapOf<ElementKey, MutableMap<ContentKey, ElementTransformations>>()
+    private val cache = mutableMapOf<ElementKey, MutableMap<ContentKey, ElementTransformations?>>()
 
-    internal fun transformations(element: ElementKey, content: ContentKey): ElementTransformations {
+    internal fun transformations(
+        element: ElementKey,
+        content: ContentKey,
+    ): ElementTransformations? {
         return cache
             .getOrPut(element) { mutableMapOf() }
             .getOrPut(content) { computeTransformations(element, content) }
     }
 
+    internal fun hasTransformation(element: ElementKey, content: ContentKey): Boolean {
+        return transformations(element, content) != null
+    }
+
     /** Filter [transformationMatchers] to compute the [ElementTransformations] of [element]. */
     private fun computeTransformations(
         element: ElementKey,
         content: ContentKey,
-    ): ElementTransformations {
+    ): ElementTransformations? {
         var shared: TransformationWithRange<SharedElementTransformation>? = null
         var offset: TransformationWithRange<PropertyTransformation<Offset>>? = null
         var size: TransformationWithRange<PropertyTransformation<IntSize>>? = null
@@ -338,7 +345,13 @@
             }
         }
 
-        return ElementTransformations(shared, offset, size, drawScale, alpha)
+        return if (
+            shared == null && offset == null && size == null && drawScale == null && alpha == null
+        ) {
+            null
+        } else {
+            ElementTransformations(shared, offset, size, drawScale, alpha)
+        }
     }
 
     private fun throwIfNotNull(
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt
index 9de297f..ed3a5ca 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt
@@ -81,8 +81,9 @@
 ): TransformationWithRange<SharedElementTransformation>? {
     val transformationSpec = transition.transformationSpec
     val sharedInFromContent =
-        transformationSpec.transformations(element, transition.fromContent).shared
-    val sharedInToContent = transformationSpec.transformations(element, transition.toContent).shared
+        transformationSpec.transformations(element, transition.fromContent)?.shared
+    val sharedInToContent =
+        transformationSpec.transformations(element, transition.toContent)?.shared
 
     // The sharedElement() transformation must either be null or be the same in both contents.
     if (sharedInFromContent != sharedInToContent) {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
index 3716df5..8c5a727 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
@@ -31,6 +31,7 @@
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.zIndex
+import com.android.compose.animation.scene.Ancestor
 import com.android.compose.animation.scene.AnimatedState
 import com.android.compose.animation.scene.ContentKey
 import com.android.compose.animation.scene.ContentScope
@@ -181,16 +182,17 @@
         modifier: Modifier,
         builder: SceneTransitionLayoutScope.() -> Unit,
     ) {
+        val ancestors =
+            remember(layoutImpl, contentKey, layoutImpl.ancestors) {
+                layoutImpl.ancestors + Ancestor(layoutImpl, contentKey)
+            }
         SceneTransitionLayoutForTesting(
             state,
             modifier,
             onLayoutImpl = null,
             builder = builder,
             sharedElementMap = layoutImpl.elements,
-            ancestorContentKeys =
-                remember(layoutImpl.ancestorContentKeys, contentKey) {
-                    layoutImpl.ancestorContentKeys + contentKey
-                },
+            ancestors = ancestors,
             lookaheadScope = layoutImpl.lookaheadScope,
         )
     }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
index c69129b..6769032 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
@@ -2208,6 +2208,7 @@
     }
 
     @Test
+    @Ignore("b/363964445")
     fun interruption_considerPreviousUniqueState() {
         @Composable
         fun SceneScope.Foo(modifier: Modifier = Modifier) {
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedElementTransformationTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedElementTransformationTest.kt
new file mode 100644
index 0000000..0da422b
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedElementTransformationTest.kt
@@ -0,0 +1,410 @@
+/*
+ * 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.compose.animation.scene.transformation
+
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.tween
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.test.SemanticsNodeInteraction
+import androidx.compose.ui.test.assertPositionInRootIsEqualTo
+import androidx.compose.ui.test.isNotDisplayed
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compose.animation.scene.ContentScope
+import com.android.compose.animation.scene.ElementKey
+import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
+import com.android.compose.animation.scene.Scale
+import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.SceneTransitionLayout
+import com.android.compose.animation.scene.SceneTransitions
+import com.android.compose.animation.scene.TestScenes
+import com.android.compose.animation.scene.testNestedTransition
+import com.android.compose.animation.scene.testing.lastAlphaForTesting
+import com.android.compose.animation.scene.testing.lastScaleForTesting
+import com.android.compose.animation.scene.transitions
+import com.android.compose.test.assertSizeIsEqualTo
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class NestedElementTransformationTest {
+    @get:Rule val rule = createComposeRule()
+
+    private object Scenes {
+        val NestedSceneA = SceneKey("NestedSceneA")
+        val NestedSceneB = SceneKey("NestedSceneB")
+        val NestedNestedSceneA = SceneKey("NestedNestedSceneA")
+        val NestedNestedSceneB = SceneKey("NestedNestedSceneB")
+    }
+
+    // Variants are named: nestingDepth + sceneNameSuffix
+    private val elementVariant0A =
+        TestElement(ElementKey("0A"), 0.dp, 0.dp, 100.dp, 100.dp, Color.Red)
+    private val elementVariant0B =
+        TestElement(ElementKey("0B"), 100.dp, 100.dp, 20.dp, 20.dp, Color.Cyan)
+    private val elementVariant1A =
+        TestElement(ElementKey("1A"), 40.dp, 80.dp, 60.dp, 20.dp, Color.Blue)
+    private val elementVariant1B =
+        TestElement(ElementKey("1B"), 80.dp, 40.dp, 140.dp, 180.dp, Color.Yellow)
+    private val elementVariant2A =
+        TestElement(ElementKey("2A"), 120.dp, 240.dp, 20.dp, 140.dp, Color.Green)
+    private val elementVariant2B =
+        TestElement(ElementKey("2B"), 200.dp, 320.dp, 40.dp, 70.dp, Color.Magenta)
+
+    private class TestElement(
+        val key: ElementKey,
+        val x: Dp,
+        val y: Dp,
+        val width: Dp,
+        val height: Dp,
+        val color: Color = Color.Black,
+        val alpha: Float = 0.8f,
+    )
+
+    @Composable
+    private fun ContentScope.TestElement(element: TestElement) {
+        Box(Modifier.fillMaxSize()) {
+            Box(
+                Modifier.offset(element.x, element.y)
+                    .element(element.key)
+                    .size(element.width, element.height)
+                    .background(element.color)
+                    .alpha(element.alpha)
+            )
+        }
+    }
+
+    private fun createState(
+        startScene: SceneKey,
+        transitions: SceneTransitions = SceneTransitions.Empty,
+    ): MutableSceneTransitionLayoutState {
+        return rule.runOnUiThread { MutableSceneTransitionLayoutState(startScene, transitions) }
+    }
+
+    private val threeNestedStls:
+        @Composable
+        (states: List<MutableSceneTransitionLayoutState>) -> Unit =
+        { states ->
+            SceneTransitionLayout(states[0]) {
+                scene(TestScenes.SceneA, content = { TestElement(elementVariant0A) })
+                scene(
+                    TestScenes.SceneB,
+                    content = {
+                        Box(Modifier.fillMaxSize()) {
+                            TestElement(elementVariant0B)
+                            NestedSceneTransitionLayout(states[1], modifier = Modifier) {
+                                scene(Scenes.NestedSceneA) {
+                                    Box(Modifier.fillMaxSize()) {
+                                        TestElement(elementVariant1A)
+                                        NestedSceneTransitionLayout(
+                                            state = states[2],
+                                            modifier = Modifier,
+                                        ) {
+                                            scene(Scenes.NestedNestedSceneA) {
+                                                TestElement(elementVariant2A)
+                                            }
+                                            scene(Scenes.NestedNestedSceneB) {
+                                                TestElement(elementVariant2B)
+                                            }
+                                        }
+                                    }
+                                }
+                                scene(Scenes.NestedSceneB) { TestElement(elementVariant1B) }
+                            }
+                        }
+                    },
+                )
+            }
+        }
+
+    @Test
+    fun transitionInNestedNestedStl_transitionsOut() {
+        rule.testNestedTransition(
+            states =
+                listOf(
+                    createState(TestScenes.SceneB),
+                    createState(Scenes.NestedSceneA),
+                    createState(
+                        Scenes.NestedNestedSceneA,
+                        transitions {
+                            from(from = Scenes.NestedNestedSceneA, to = Scenes.NestedNestedSceneB) {
+                                spec = tween(16 * 4, easing = LinearEasing)
+                                translate(elementVariant2A.key, x = 100.dp, y = 50.dp)
+                                scaleSize(elementVariant2A.key, width = 2f, height = 0.5f)
+                                scaleDraw(elementVariant2A.key, scaleX = 4f, scaleY = 0.25f)
+                                fade(elementVariant2A.key)
+                            }
+                        },
+                    ),
+                ),
+            transitionLayout = threeNestedStls,
+            changeState = { it[2].setTargetScene(Scenes.NestedNestedSceneB, this) },
+        ) {
+            before { onElement(elementVariant2A.key).assertElementVariant(elementVariant2A) }
+            atAllFrames(4) {
+                onElement(elementVariant2A.key)
+                    .assertPositionInRootIsEqualTo(
+                        interpolate(elementVariant2A.x, elementVariant2A.x + 100.dp),
+                        interpolate(elementVariant2A.y, elementVariant2A.y + 50.dp),
+                    )
+                    .assertSizeIsEqualTo(
+                        interpolate(elementVariant2A.width, elementVariant2A.width * 2f),
+                        interpolate(elementVariant2A.height, elementVariant2A.height * 0.5f),
+                    )
+                val semanticNode = onElement(elementVariant2A.key).fetchSemanticsNode()
+                assertThat(semanticNode.lastAlphaForTesting).isEqualTo(interpolate(1f, 0f))
+                assertThat(semanticNode.lastScaleForTesting)
+                    .isEqualTo(interpolate(Scale(1f, 1f), Scale(4f, 0.25f)))
+            }
+            after { onElement(elementVariant2A.key).isNotDisplayed() }
+        }
+    }
+
+    @Test
+    fun transitionInNestedNestedStl_transitionsIn() {
+        rule.testNestedTransition(
+            states =
+                listOf(
+                    createState(TestScenes.SceneB),
+                    createState(Scenes.NestedSceneA),
+                    createState(
+                        Scenes.NestedNestedSceneB,
+                        transitions {
+                            from(from = Scenes.NestedNestedSceneB) {
+                                spec = tween(16 * 4, easing = LinearEasing)
+                                translate(elementVariant2A.key, x = 100.dp, y = 50.dp)
+                                scaleSize(elementVariant2A.key, width = 2f, height = 0.5f)
+                            }
+                        },
+                    ),
+                ),
+            transitionLayout = threeNestedStls,
+            changeState = { it[2].setTargetScene(Scenes.NestedNestedSceneA, this) },
+        ) {
+            before { onElement(elementVariant2A.key).isNotDisplayed() }
+            atAllFrames(4) {
+                onElement(elementVariant2A.key)
+                    .assertPositionInRootIsEqualTo(
+                        interpolate(elementVariant2A.x + 100.dp, elementVariant2A.x),
+                        interpolate(elementVariant2A.y + 50.dp, elementVariant2A.y),
+                    )
+                    .assertSizeIsEqualTo(
+                        interpolate(elementVariant2A.width * 2f, elementVariant2A.width),
+                        interpolate(elementVariant2A.height * 0.5f, elementVariant2A.height),
+                    )
+            }
+            after { onElement(elementVariant2A.key).assertElementVariant(elementVariant2A) }
+        }
+    }
+
+    @Test
+    fun transitionInNestedStl_elementInNestedNestedStl_transitionsIn() {
+        rule.testNestedTransition(
+            states =
+                listOf(
+                    createState(TestScenes.SceneB),
+                    createState(
+                        Scenes.NestedSceneB,
+                        transitions {
+                            from(from = Scenes.NestedSceneB, to = Scenes.NestedSceneA) {
+                                spec = tween(16 * 4, easing = LinearEasing)
+                                translate(elementVariant2A.key, x = 100.dp, y = 50.dp)
+                                scaleSize(elementVariant2A.key, width = 2f, height = 0.5f)
+                            }
+                        },
+                    ),
+                    createState(Scenes.NestedNestedSceneA),
+                ),
+            transitionLayout = threeNestedStls,
+            changeState = { it[1].setTargetScene(Scenes.NestedSceneA, this) },
+        ) {
+            before { onElement(elementVariant2A.key).isNotDisplayed() }
+            atAllFrames(4) {
+                onElement(elementVariant2A.key)
+                    .assertPositionInRootIsEqualTo(
+                        interpolate(elementVariant2A.x + 100.dp, elementVariant2A.x),
+                        interpolate(elementVariant2A.y + 50.dp, elementVariant2A.y),
+                    )
+                    .assertSizeIsEqualTo(
+                        interpolate(elementVariant2A.width * 2f, elementVariant2A.width),
+                        interpolate(elementVariant2A.height * 0.5f, elementVariant2A.height),
+                    )
+            }
+            after { onElement(elementVariant2A.key).assertElementVariant(elementVariant2A) }
+        }
+    }
+
+    @Test
+    fun transitionInRootStl_elementsInAllLayers_transitionInAndOut() {
+        rule.testNestedTransition(
+            states =
+                listOf(
+                    createState(
+                        TestScenes.SceneB,
+                        transitions {
+                            to(to = TestScenes.SceneA) {
+                                spec = tween(16 * 4, easing = LinearEasing)
+
+                                // transitions out
+                                translate(elementVariant2A.key, x = 100.dp, y = 50.dp)
+                                scaleSize(elementVariant2A.key, width = 2f, height = 0.5f)
+
+                                // transitions out
+                                translate(elementVariant0B.key, x = 200.dp, y = 20.dp)
+                                scaleSize(elementVariant0B.key, width = 3f, height = 0.2f)
+
+                                // transitions out
+                                translate(elementVariant1A.key, x = 300.dp, y = 10.dp)
+                                scaleSize(elementVariant1A.key, width = 4f, height = 0.1f)
+
+                                // transitions in
+                                translate(elementVariant0A.key, x = 400.dp, y = 40.dp)
+                                scaleSize(elementVariant0A.key, width = 0.5f, height = 2f)
+                            }
+                        },
+                    ),
+                    createState(Scenes.NestedSceneA),
+                    createState(Scenes.NestedNestedSceneA),
+                ),
+            transitionLayout = threeNestedStls,
+            changeState = { it[0].setTargetScene(TestScenes.SceneA, this) },
+        ) {
+            before {
+                onElement(elementVariant2A.key).assertElementVariant(elementVariant2A)
+                onElement(elementVariant0B.key).assertElementVariant(elementVariant0B)
+                onElement(elementVariant1A.key).assertElementVariant(elementVariant1A)
+                onElement(elementVariant0A.key).isNotDisplayed()
+            }
+            atAllFrames(4) {
+                onElement(elementVariant2A.key)
+                    .assertPositionInRootIsEqualTo(
+                        interpolate(elementVariant2A.x, elementVariant2A.x + 100.dp),
+                        interpolate(elementVariant2A.y, elementVariant2A.y + 50.dp),
+                    )
+                    .assertSizeIsEqualTo(
+                        interpolate(elementVariant2A.width, elementVariant2A.width * 2f),
+                        interpolate(elementVariant2A.height, elementVariant2A.height * 0.5f),
+                    )
+
+                onElement(elementVariant0B.key)
+                    .assertPositionInRootIsEqualTo(
+                        interpolate(elementVariant0B.x, elementVariant0B.x + 200.dp),
+                        interpolate(elementVariant0B.y, elementVariant0B.y + 20.dp),
+                    )
+                    .assertSizeIsEqualTo(
+                        interpolate(elementVariant0B.width, elementVariant0B.width * 3f),
+                        interpolate(elementVariant0B.height, elementVariant0B.height * 0.2f),
+                    )
+
+                onElement(elementVariant1A.key)
+                    .assertPositionInRootIsEqualTo(
+                        interpolate(elementVariant1A.x, elementVariant1A.x + 300.dp),
+                        interpolate(elementVariant1A.y, elementVariant1A.y + 10.dp),
+                    )
+                    .assertSizeIsEqualTo(
+                        interpolate(elementVariant1A.width, elementVariant1A.width * 4f),
+                        interpolate(elementVariant1A.height, elementVariant1A.height * 0.1f),
+                    )
+
+                onElement(elementVariant0A.key)
+                    .assertPositionInRootIsEqualTo(
+                        interpolate(elementVariant0A.x + 400.dp, elementVariant0A.x),
+                        interpolate(elementVariant0A.y + 40.dp, elementVariant0A.y),
+                    )
+                    .assertSizeIsEqualTo(
+                        interpolate(elementVariant0A.width * 0.5f, elementVariant0A.width),
+                        interpolate(elementVariant0A.height * 2f, elementVariant0A.height),
+                    )
+            }
+            after {
+                onElement(elementVariant2A.key).isNotDisplayed()
+                onElement(elementVariant0B.key).isNotDisplayed()
+                onElement(elementVariant1A.key).isNotDisplayed()
+                onElement(elementVariant0A.key).assertElementVariant(elementVariant0A)
+            }
+        }
+    }
+
+    @Test
+    fun transitionInMultipleStls_rootIsTakingControl() {
+        rule.testNestedTransition(
+            states =
+                listOf(
+                    createState(
+                        TestScenes.SceneB,
+                        transitions {
+                            to(to = TestScenes.SceneA) {
+                                spec = tween(16 * 4, easing = LinearEasing)
+                                translate(elementVariant2A.key, x = 100.dp, y = 50.dp)
+                            }
+                        },
+                    ),
+                    createState(
+                        Scenes.NestedSceneA,
+                        transitions {
+                            to(to = Scenes.NestedSceneB) {
+                                spec = tween(16 * 4, easing = LinearEasing)
+                                translate(elementVariant2A.key, x = 200.dp, y = 150.dp)
+                            }
+                        },
+                    ),
+                    createState(
+                        Scenes.NestedNestedSceneA,
+                        transitions {
+                            to(to = Scenes.NestedNestedSceneB) {
+                                spec = tween(16 * 4, easing = LinearEasing)
+                                translate(elementVariant2A.key, x = 300.dp, y = 250.dp)
+                            }
+                        },
+                    ),
+                ),
+            transitionLayout = threeNestedStls,
+            changeState = {
+                it[2].setTargetScene(Scenes.NestedNestedSceneB, this)
+                it[1].setTargetScene(Scenes.NestedSceneB, this)
+                it[0].setTargetScene(TestScenes.SceneA, this)
+            },
+        ) {
+            before { onElement(elementVariant2A.key).assertElementVariant(elementVariant2A) }
+            atAllFrames(4) {
+                onElement(elementVariant2A.key)
+                    .assertPositionInRootIsEqualTo(
+                        interpolate(elementVariant2A.x, elementVariant2A.x + 100.dp),
+                        interpolate(elementVariant2A.y, elementVariant2A.y + 50.dp),
+                    )
+            }
+            after { onElement(elementVariant2A.key).isNotDisplayed() }
+        }
+    }
+
+    private fun SemanticsNodeInteraction.assertElementVariant(variant: TestElement) {
+        assertPositionInRootIsEqualTo(variant.x, variant.y)
+        assertSizeIsEqualTo(variant.width, variant.height)
+    }
+}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSharedElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSharedElementTest.kt
index c6ef8cf..d8b7136 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSharedElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/NestedSharedElementTest.kt
@@ -61,7 +61,7 @@
         val NestedNestedSceneB = SceneKey("NestedNestedSceneB")
     }
 
-    private val elementVariant1 = SharedElement(0.dp, 0.dp, 100.dp, 100.dp, Color.Red)
+    private val elementVariant1 = SharedElement(100.dp, 100.dp, 100.dp, 100.dp, Color.Red)
     private val elementVariant2 = SharedElement(40.dp, 80.dp, 60.dp, 20.dp, Color.Blue)
     private val elementVariant3 = SharedElement(80.dp, 40.dp, 140.dp, 180.dp, Color.Yellow)
     private val elementVariant4 = SharedElement(120.dp, 240.dp, 20.dp, 140.dp, Color.Green)
@@ -223,7 +223,8 @@
                 // In SceneA, Foo leaves to the left edge.
                 translate(TestElements.Foo.inScene(TestScenes.SceneA), Edge.Left, false)
 
-                // We can't reference the element inside the NestedSTL as of today
+                // In NestedSceneA, Foo comes in from the top edge.
+                translate(TestElements.Foo.inScene(Scenes.NestedSceneA), Edge.Top, false)
             },
         ) {
             before { onElement(TestElements.Foo).assertElementVariant(elementVariant1) }
@@ -234,6 +235,11 @@
                         elementVariant1.y,
                     )
                     .assertSizeIsEqualTo(elementVariant1.width, elementVariant1.height)
+                onElement(TestElements.Foo, scene = Scenes.NestedSceneA)
+                    .assertPositionInRootIsEqualTo(
+                        elementVariant2.x,
+                        interpolate(0.dp, elementVariant2.y),
+                    )
             }
             after { onElement(TestElements.Foo).assertElementVariant(elementVariant2) }
         }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/SharedElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/SharedElementTest.kt
index 47c10f5..0dd08d9 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/SharedElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/SharedElementTest.kt
@@ -18,11 +18,13 @@
 
 import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.tween
+import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.offset
 import androidx.compose.foundation.layout.size
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.test.assertIsNotDisplayed
 import androidx.compose.ui.test.assertPositionInRootIsEqualTo
 import androidx.compose.ui.test.junit4.createComposeRule
@@ -47,11 +49,21 @@
         rule.testTransition(
             fromSceneContent = {
                 // Foo is at (10, 50) with a size of (20, 80).
-                Box(Modifier.offset(10.dp, 50.dp).element(TestElements.Foo).size(20.dp, 80.dp))
+                Box(
+                    Modifier.offset(10.dp, 50.dp)
+                        .element(TestElements.Foo)
+                        .size(20.dp, 80.dp)
+                        .background(Color.Red)
+                )
             },
             toSceneContent = {
                 // Foo is at (50, 70) with a size of (10, 40).
-                Box(Modifier.offset(50.dp, 70.dp).element(TestElements.Foo).size(10.dp, 40.dp))
+                Box(
+                    Modifier.offset(50.dp, 70.dp)
+                        .element(TestElements.Foo)
+                        .size(10.dp, 40.dp)
+                        .background(Color.Blue)
+                )
             },
             transition = {
                 spec = tween(16 * 4, easing = LinearEasing)
@@ -88,13 +100,23 @@
             fromSceneContent = {
                 Box(Modifier.fillMaxSize()) {
                     // Foo is at (10, 50).
-                    Box(Modifier.offset(10.dp, 50.dp).element(TestElements.Foo))
+                    Box(
+                        Modifier.offset(10.dp, 50.dp)
+                            .element(TestElements.Foo)
+                            .size(20.dp)
+                            .background(Color.Red)
+                    )
                 }
             },
             toSceneContent = {
                 Box(Modifier.fillMaxSize()) {
                     // Foo is at (50, 60).
-                    Box(Modifier.offset(50.dp, 60.dp).element(TestElements.Foo))
+                    Box(
+                        Modifier.offset(50.dp, 60.dp)
+                            .element(TestElements.Foo)
+                            .size(20.dp)
+                            .background(Color.Blue)
+                    )
                 }
             },
             transition = {
@@ -104,7 +126,11 @@
                 sharedElement(TestElements.Foo, enabled = false)
 
                 // In SceneA, Foo leaves to the left edge.
-                translate(TestElements.Foo.inScene(TestScenes.SceneA), Edge.Left)
+                translate(
+                    TestElements.Foo.inScene(TestScenes.SceneA),
+                    Edge.Left,
+                    startsOutsideLayoutBounds = false,
+                )
 
                 // In SceneB, Foo comes from the bottom edge.
                 translate(TestElements.Foo.inScene(TestScenes.SceneB), Edge.Bottom)
diff --git a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt
index 124b61e..bc160fc 100644
--- a/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt
+++ b/packages/SystemUI/compose/scene/tests/utils/src/com/android/compose/animation/scene/TestTransition.kt
@@ -25,6 +25,7 @@
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.semantics.SemanticsNode
 import androidx.compose.ui.test.SemanticsNodeInteraction
 import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
@@ -63,6 +64,9 @@
      * Important: [timestamp] must be a multiple of 16 (the duration of a frame on the JVM/Android).
      * There is no intermediary state between `t` and `t + 16` , so testing transitions outside of
      * `t = 0`, `t = 16`, `t = 32`, etc does not make sense.
+     *
+     * @param builder the builder can run assertions and is passed the CoroutineScope such that the
+     *   test can start transitions at any desired point in time.
      */
     fun at(timestamp: Long, builder: TransitionTestAssertionScope.() -> Unit)
 
@@ -85,7 +89,7 @@
 }
 
 @TransitionTestDsl
-interface TransitionTestAssertionScope {
+interface TransitionTestAssertionScope : CoroutineScope {
     /**
      * Assert on [element].
      *
@@ -312,6 +316,20 @@
     )
 }
 
+fun ComposeContentTestRule.testNestedTransition(
+    states: List<MutableSceneTransitionLayoutState>,
+    changeState: CoroutineScope.(states: List<MutableSceneTransitionLayoutState>) -> Unit,
+    transitionLayout: @Composable (states: List<MutableSceneTransitionLayoutState>) -> Unit,
+    builder: TransitionTestBuilder.() -> Unit,
+) {
+    testTransition(
+        state = states[0],
+        changeState = { changeState(states) },
+        transitionLayout = { transitionLayout(states) },
+        builder = builder,
+    )
+}
+
 /** Test the transition from [state] to [to]. */
 fun ComposeContentTestRule.testTransition(
     state: MutableSceneTransitionLayoutState,
@@ -319,9 +337,15 @@
     transitionLayout: @Composable (state: MutableSceneTransitionLayoutState) -> Unit,
     builder: TransitionTestBuilder.() -> Unit,
 ) {
-    val test = transitionTest(builder)
+    lateinit var coroutineScope: CoroutineScope
+    setContent {
+        coroutineScope = rememberCoroutineScope()
+        transitionLayout(state)
+    }
+
     val assertionScope =
-        object : AutoTransitionTestAssertionScope {
+        object : AutoTransitionTestAssertionScope, CoroutineScope by coroutineScope {
+
             var progress = 0f
 
             override fun onElement(
@@ -338,6 +362,16 @@
                     from is Int && to is Int -> lerp(from, to, progress)
                     from is Long && to is Long -> lerp(from, to, progress)
                     from is Dp && to is Dp -> lerp(from, to, progress)
+                    from is Scale && to is Scale ->
+                        Scale(
+                            lerp(from.scaleX, to.scaleX, progress),
+                            lerp(from.scaleY, to.scaleY, progress),
+                            interpolate(from.pivot, to.pivot),
+                        )
+
+                    from is Offset && to is Offset ->
+                        Offset(lerp(from.x, to.x, progress), lerp(from.y, to.y, progress))
+
                     else ->
                         throw UnsupportedOperationException(
                             "Interpolation not supported for this type"
@@ -347,14 +381,9 @@
             }
         }
 
-    lateinit var coroutineScope: CoroutineScope
-    setContent {
-        coroutineScope = rememberCoroutineScope()
-        transitionLayout(state)
-    }
-
     // Wait for the UI to be idle then test the before state.
     waitForIdle()
+    val test = transitionTest(builder)
     test.before(assertionScope)
 
     // Manually advance the clock to the start of the animation.
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java
index 80de087..2665910 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java
@@ -29,6 +29,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.accessibility.utils.TestUtils;
@@ -58,13 +59,15 @@
 
     @Mock
     private AccessibilityManager mAccessibilityManager;
+    @Mock
+    private HearingAidDeviceManager mHearingAidDeviceManager;
 
     @Before
     public void setUp() throws Exception {
         final WindowManager stubWindowManager = mContext.getSystemService(WindowManager.class);
         final SecureSettings mockSecureSettings = TestUtils.mockSecureSettings();
         final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, mAccessibilityManager,
-                mockSecureSettings);
+                mockSecureSettings, mHearingAidDeviceManager);
         final MenuViewAppearance stubMenuViewAppearance = new MenuViewAppearance(mContext,
                 stubWindowManager);
         final MenuView stubMenuView = spy(new MenuView(mContext, stubMenuViewModel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepositoryTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepositoryTest.java
index 24f3a29..785493f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepositoryTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepositoryTest.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.accessibility.floatingmenu;
 
+import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
 
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -25,11 +26,13 @@
 
 import android.content.Context;
 import android.content.res.Configuration;
+import android.platform.test.annotations.EnableFlags;
 import android.view.accessibility.AccessibilityManager;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.util.settings.SecureSettings;
 
@@ -45,6 +48,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
+import java.util.concurrent.Executor;
 
 /** Tests for {@link MenuInfoRepository}. */
 @RunWith(AndroidJUnit4.class)
@@ -55,9 +59,10 @@
 
     @Mock
     private AccessibilityManager mAccessibilityManager;
-
     @Mock
-    private MenuInfoRepository.OnSettingsContentsChanged mMockSettingsContentsChanged;
+    private HearingAidDeviceManager mHearingAidDeviceManager;
+    @Mock
+    private MenuInfoRepository.OnContentsChanged mMockSettingsContentsChanged;
     @Mock
     private SecureSettings mSecureSettings;
 
@@ -72,7 +77,7 @@
                 anyInt());
 
         mMenuInfoRepository = new MenuInfoRepository(mContext, mAccessibilityManager,
-                mMockSettingsContentsChanged, mSecureSettings);
+                mMockSettingsContentsChanged, mSecureSettings, mHearingAidDeviceManager);
     }
 
     @After
@@ -103,4 +108,16 @@
 
         verify(mMockSettingsContentsChanged).onTargetFeaturesChanged(any());
     }
+
+    @Test
+    @EnableFlags(
+            com.android.settingslib.flags.Flags.FLAG_HEARING_DEVICE_SET_CONNECTION_STATUS_REPORT)
+    public void registerObservers_addHearingDeviceTarget_verifyRegisterConnectionStatusListener() {
+        mShortcutTargets.add(ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
+        mMenuInfoRepository.registerObserversAndCallbacks();
+
+        verify(mHearingAidDeviceManager).registerConnectionStatusListener(
+                any(HearingAidDeviceManager.ConnectionStatusListener.class), any(
+                        Executor.class));
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
index 157cccc..241da5f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
@@ -41,6 +41,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.accessibility.utils.TestUtils;
@@ -68,6 +69,8 @@
 
     @Mock
     private AccessibilityManager mAccessibilityManager;
+    @Mock
+    private HearingAidDeviceManager mHearingAidDeviceManager;
     private final SecureSettings mSecureSettings = TestUtils.mockSecureSettings();
     private RecyclerView mStubListView;
     private MenuView mMenuView;
@@ -84,7 +87,7 @@
         final MenuViewAppearance stubMenuViewAppearance = new MenuViewAppearance(mContext,
                 stubWindowManager);
         final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, mAccessibilityManager,
-                mSecureSettings);
+                mSecureSettings, mHearingAidDeviceManager);
 
         final int halfScreenHeight =
                 stubWindowManager.getCurrentWindowMetrics().getBounds().height() / 2;
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java
index 46f076a..fbd8a71 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java
@@ -41,6 +41,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.accessibility.dialog.AccessibilityTarget;
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.accessibility.MotionEventHelper;
@@ -82,13 +83,15 @@
 
     @Mock
     private AccessibilityManager mAccessibilityManager;
+    @Mock
+    private HearingAidDeviceManager mHearingAidDeviceManager;
 
     @Before
     public void setUp() throws Exception {
         final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
         final SecureSettings secureSettings = TestUtils.mockSecureSettings();
         final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, mAccessibilityManager,
-                secureSettings);
+                secureSettings, mHearingAidDeviceManager);
         final MenuViewAppearance stubMenuViewAppearance = new MenuViewAppearance(mContext,
                 windowManager);
         mStubMenuView = new MenuView(mContext, stubMenuViewModel, stubMenuViewAppearance,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java
index fcdeff9..4f04310 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java
@@ -41,6 +41,7 @@
 
 import com.android.app.viewcapture.ViewCapture;
 import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.util.settings.SecureSettings;
@@ -68,6 +69,8 @@
 
     @Mock
     private AccessibilityManager mAccessibilityManager;
+    @Mock
+    private HearingAidDeviceManager mHearingAidDeviceManager;
 
     @Mock
     private SecureSettings mSecureSettings;
@@ -93,7 +96,7 @@
         when(mWindowMetrics.getWindowInsets()).thenReturn(stubDisplayInsets());
         mMenuViewLayerController = new MenuViewLayerController(mContext, mWindowManager,
                 viewCaptureAwareWm, mAccessibilityManager, mSecureSettings,
-                mock(NavigationModeController.class));
+                mock(NavigationModeController.class), mHearingAidDeviceManager);
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java
index ee8ce17..cb7c205 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java
@@ -37,6 +37,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.systemui.Flags;
 import com.android.systemui.Prefs;
 import com.android.systemui.SysuiTestCase;
@@ -70,6 +71,8 @@
 
     @Mock
     private AccessibilityManager mAccessibilityManager;
+    @Mock
+    private HearingAidDeviceManager mHearingAidDeviceManager;
 
     private SysuiTestableContext mSpyContext;
 
@@ -90,7 +93,7 @@
 
         final SecureSettings secureSettings = TestUtils.mockSecureSettings();
         final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, mAccessibilityManager,
-                secureSettings);
+                secureSettings, mHearingAidDeviceManager);
         final WindowManager stubWindowManager = mContext.getSystemService(WindowManager.class);
         mStubMenuViewAppearance = new MenuViewAppearance(mSpyContext, stubWindowManager);
         mMenuView = spy(new MenuView(mSpyContext, stubMenuViewModel, mStubMenuViewAppearance,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
index 714461b..daebf13 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
@@ -88,7 +88,7 @@
 
         listener.enable();
         verify(mDisplayManager).registerDisplayListener(any(), same(mHandler),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_CHANGED));
     }
 
     @Test
@@ -112,7 +112,7 @@
 
         // The listener should register a display listener.
         verify(mDisplayManager).registerDisplayListener(mDisplayListenerCaptor.capture(),
-                same(mHandler), eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED));
+                same(mHandler), eq(DisplayManager.EVENT_TYPE_DISPLAY_CHANGED));
 
         // mOnChangedCallback should be invoked for all calls to onDisplayChanged.
         mDisplayListenerCaptor.getValue().onDisplayChanged(123);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt
index f4cffc5..2e8efdb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt
@@ -20,7 +20,7 @@
 import android.hardware.display.BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE
 import android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF
 import android.hardware.display.DisplayManager
-import android.hardware.display.DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS
+import android.hardware.display.DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS
 import android.view.Display
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -120,7 +120,7 @@
                         capture(listenerCaptor),
                         eq(null),
                         eq(0),
-                        eq(PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS),
+                        eq(PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS),
                     )
 
                 val newBrightness = BrightnessInfo(0.6f, 0.3f, 0.9f)
@@ -159,7 +159,7 @@
                         capture(listenerCaptor),
                         eq(null),
                         eq(0),
-                        eq(PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS),
+                        eq(PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS),
                     )
 
                 changeBrightnessInfoAndNotify(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
index d70af28..b70f46c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
@@ -25,10 +25,12 @@
 import android.widget.RemoteViews
 import androidx.test.filters.SmallTest
 import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.systemui.Flags.FLAG_BOUNCER_UI_REVAMP
 import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
 import com.android.systemui.Flags.FLAG_COMMUNAL_RESPONSIVE_GRID
 import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_DIRECT_EDIT_MODE
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
 import com.android.systemui.communal.data.model.CommunalSmartspaceTimer
 import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository
 import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
@@ -69,6 +71,7 @@
 import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.log.logcatLogBuffer
@@ -184,6 +187,7 @@
             logcatLogBuffer("CommunalViewModelTest"),
             metricsLogger,
             kosmos.mediaCarouselController,
+            kosmos.blurConfig,
         )
     }
 
@@ -893,6 +897,20 @@
             assertThat(selectedKey2).isEqualTo(key)
         }
 
+    @Test
+    @EnableFlags(FLAG_BOUNCER_UI_REVAMP)
+    fun uiIsBlurred_whenPrimaryBouncerIsShowing() =
+        testScope.runTest {
+            val viewModel = createViewModel()
+            val isUiBlurred by collectLastValue(viewModel.isUiBlurred)
+
+            kosmos.fakeKeyguardBouncerRepository.setPrimaryShow(true)
+            assertThat(isUiBlurred).isTrue()
+
+            kosmos.fakeKeyguardBouncerRepository.setPrimaryShow(false)
+            assertThat(isUiBlurred).isFalse()
+        }
+
     private suspend fun setIsMainUser(isMainUser: Boolean) {
         val user = if (isMainUser) MAIN_USER_INFO else SECONDARY_USER_INFO
         with(userRepository) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
index e6e5665..c585d5c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
@@ -541,7 +541,7 @@
                 connectedDisplayListener.capture(),
                 eq(testHandler),
                 eq(0),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_CONNECTION_CHANGED),
             )
         return flowValue
     }
@@ -558,9 +558,9 @@
                 displayListener.capture(),
                 eq(testHandler),
                 eq(
-                    DisplayManager.EVENT_FLAG_DISPLAY_ADDED or
-                        DisplayManager.EVENT_FLAG_DISPLAY_CHANGED or
-                        DisplayManager.EVENT_FLAG_DISPLAY_REMOVED
+                    DisplayManager.EVENT_TYPE_DISPLAY_ADDED or
+                        DisplayManager.EVENT_TYPE_DISPLAY_CHANGED or
+                        DisplayManager.EVENT_TYPE_DISPLAY_REMOVED
                 ),
             )
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepositoryImplTest.kt
index f68a1b5..eae5728 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepositoryImplTest.kt
@@ -16,7 +16,7 @@
 
 package com.android.systemui.display.data.repository
 
-import android.content.testableContext
+import android.content.Context
 import android.platform.test.annotations.EnableFlags
 import android.view.Display
 import android.view.layoutInflater
@@ -24,6 +24,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.SysuiTestableContext
 import com.android.systemui.display.shared.model.DisplayWindowProperties
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.testScope
@@ -36,8 +37,12 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.Mockito.doAnswer
+import org.mockito.kotlin.any
 import org.mockito.kotlin.doReturn
 import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.whenever
 
 @EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
 @RunWith(AndroidJUnit4::class)
@@ -48,7 +53,8 @@
     private val fakeDisplayRepository = kosmos.displayRepository
     private val testScope = kosmos.testScope
 
-    private val applicationContext = kosmos.testableContext
+    private val applicationContext = spy(context)
+
     private val applicationWindowManager = kosmos.mockWindowManager
     private val applicationLayoutInflater = kosmos.layoutInflater
 
@@ -64,6 +70,22 @@
     }
 
     @Before
+    fun setUpContext() {
+        doAnswer { createContextForDisplay(it.arguments[0] as Display) }
+            .whenever(applicationContext)
+            .createWindowContext(any(), any(), any())
+    }
+
+    private fun createContextForDisplay(display: Display): Context {
+        if (display.displayId == BEING_REMOVED_DISPLAY_ID) {
+            // Simulate what happens when a display is being removed.
+            // Return a context with the same display id as the original context.
+            return mContext
+        }
+        return SysuiTestableContext(mContext).also { it.display = display }
+    }
+
+    @Before
     fun start() {
         repo.start()
     }
@@ -72,6 +94,7 @@
     fun addDisplays() = runBlocking {
         fakeDisplayRepository.addDisplay(createDisplay(DEFAULT_DISPLAY_ID))
         fakeDisplayRepository.addDisplay(createDisplay(NON_DEFAULT_DISPLAY_ID))
+        fakeDisplayRepository.addDisplay(createDisplay(BEING_REMOVED_DISPLAY_ID))
     }
 
     @Test
@@ -94,7 +117,7 @@
     @Test
     fun get_nonDefaultDisplayId_returnsNewStatusBarContext() =
         testScope.runTest {
-            val displayContext = repo.get(NON_DEFAULT_DISPLAY_ID, WINDOW_TYPE_FOO)
+            val displayContext = repo.get(NON_DEFAULT_DISPLAY_ID, WINDOW_TYPE_FOO)!!
 
             assertThat(displayContext.context).isNotSameInstanceAs(applicationContext)
         }
@@ -102,7 +125,7 @@
     @Test
     fun get_nonDefaultDisplayId_returnsNewWindowManager() =
         testScope.runTest {
-            val displayContext = repo.get(NON_DEFAULT_DISPLAY_ID, WINDOW_TYPE_FOO)
+            val displayContext = repo.get(NON_DEFAULT_DISPLAY_ID, WINDOW_TYPE_FOO)!!
 
             assertThat(displayContext.windowManager).isNotSameInstanceAs(applicationWindowManager)
         }
@@ -110,7 +133,7 @@
     @Test
     fun get_nonDefaultDisplayId_returnsNewLayoutInflater() =
         testScope.runTest {
-            val displayContext = repo.get(NON_DEFAULT_DISPLAY_ID, WINDOW_TYPE_FOO)
+            val displayContext = repo.get(NON_DEFAULT_DISPLAY_ID, WINDOW_TYPE_FOO)!!
 
             assertThat(displayContext.layoutInflater).isNotSameInstanceAs(applicationLayoutInflater)
         }
@@ -154,17 +177,26 @@
                 .isNotSameInstanceAs(displayContext)
         }
 
-    @Test(expected = IllegalArgumentException::class)
-    fun get_nonExistingDisplayId_throws() =
-        testScope.runTest { repo.get(NON_EXISTING_DISPLAY_ID, WINDOW_TYPE_FOO) }
+    @Test
+    fun get_nonExistingDisplayId_returnsNull() =
+        testScope.runTest {
+            assertThat(repo.get(NON_EXISTING_DISPLAY_ID, WINDOW_TYPE_FOO)).isNull()
+        }
+
+    @Test
+    fun get_displayBeingRemoved_returnsNull() =
+        testScope.runTest {
+            assertThat(repo.get(BEING_REMOVED_DISPLAY_ID, WINDOW_TYPE_FOO)).isNull()
+        }
 
     private fun createDisplay(displayId: Int) =
-        mock<Display> { on { getDisplayId() } doReturn displayId }
+        mock<Display> { on { getDisplayId() } doReturn (displayId) }
 
     companion object {
         private const val DEFAULT_DISPLAY_ID = Display.DEFAULT_DISPLAY
         private const val NON_DEFAULT_DISPLAY_ID = DEFAULT_DISPLAY_ID + 1
         private const val NON_EXISTING_DISPLAY_ID = DEFAULT_DISPLAY_ID + 2
+        private const val BEING_REMOVED_DISPLAY_ID = DEFAULT_DISPLAY_ID + 4
         private const val WINDOW_TYPE_FOO = 123
         private const val WINDOW_TYPE_BAR = 321
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayStoreImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayStoreImplTest.kt
index 6a0781b..73957eb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayStoreImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayStoreImplTest.kt
@@ -80,9 +80,9 @@
             assertThat(store.forDisplay(NON_DEFAULT_DISPLAY_ID)).isNotSameInstanceAs(instance)
         }
 
-    @Test(expected = IllegalArgumentException::class)
-    fun forDisplay_nonExistingDisplayId_throws() =
-        testScope.runTest { store.forDisplay(NON_EXISTING_DISPLAY_ID) }
+    @Test
+    fun forDisplay_nonExistingDisplayId_returnsNull() =
+        testScope.runTest { assertThat(store.forDisplay(NON_EXISTING_DISPLAY_ID)).isNull() }
 
     @Test
     fun forDisplay_afterDisplayRemoved_onDisplayRemovalActionInvoked() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt
index 28ac169..16f02c5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
 import com.android.systemui.deviceentry.shared.FaceAuthUiEvent
-import com.android.systemui.flags.Flags
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
@@ -93,9 +92,7 @@
         testScope.runTest {
             val isEnabled = collectLastValue(underTest.isLongPressHandlingEnabled)
             KeyguardState.values().forEach { keyguardState ->
-                setUpState(
-                    keyguardState = keyguardState,
-                )
+                setUpState(keyguardState = keyguardState)
 
                 if (keyguardState == KeyguardState.LOCKSCREEN) {
                     assertThat(isEnabled()).isTrue()
@@ -110,10 +107,7 @@
         testScope.runTest {
             val isEnabled = collectLastValue(underTest.isLongPressHandlingEnabled)
             KeyguardState.values().forEach { keyguardState ->
-                setUpState(
-                    keyguardState = keyguardState,
-                    isQuickSettingsVisible = true,
-                )
+                setUpState(keyguardState = keyguardState, isQuickSettingsVisible = true)
 
                 assertThat(isEnabled()).isFalse()
             }
@@ -290,22 +284,19 @@
             keyguardTransitionRepository.sendTransitionSteps(
                 from = KeyguardState.LOCKSCREEN,
                 to = KeyguardState.GONE,
-                testScope
+                testScope,
             )
             assertThat(isMenuVisible).isFalse()
 
             keyguardTransitionRepository.sendTransitionSteps(
                 from = KeyguardState.GONE,
                 to = KeyguardState.LOCKSCREEN,
-                testScope
+                testScope,
             )
             assertThat(isMenuVisible).isFalse()
         }
 
-    private suspend fun createUnderTest(
-        isLongPressFeatureEnabled: Boolean = true,
-        isRevampedWppFeatureEnabled: Boolean = true,
-    ) {
+    private suspend fun createUnderTest(isRevampedWppFeatureEnabled: Boolean = true) {
         // This needs to be re-created for each test outside of kosmos since the flag values are
         // read during initialization to set up flows. Maybe there is a better way to handle that.
         underTest =
@@ -315,10 +306,7 @@
                 transitionInteractor = kosmos.keyguardTransitionInteractor,
                 repository = keyguardRepository,
                 logger = logger,
-                featureFlags =
-                    kosmos.fakeFeatureFlagsClassic.apply {
-                        set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, isLongPressFeatureEnabled)
-                    },
+                featureFlags = kosmos.fakeFeatureFlagsClassic,
                 broadcastDispatcher = fakeBroadcastDispatcher,
                 accessibilityManager = kosmos.accessibilityManagerWrapper,
                 pulsingGestureListener = kosmos.pulsingGestureListener,
@@ -334,7 +322,7 @@
         keyguardTransitionRepository.sendTransitionSteps(
             from = KeyguardState.AOD,
             to = keyguardState,
-            testScope = testScope
+            testScope = testScope,
         )
         keyguardRepository.setQuickSettingsVisible(isVisible = isQuickSettingsVisible)
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
index 67a4332..7c694b4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
@@ -23,7 +23,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.communal.ui.view.layout.sections.CommunalTutorialIndicatorSection
 import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
 import com.android.systemui.keyguard.shared.model.KeyguardSection
 import com.android.systemui.keyguard.ui.view.KeyguardRootView
@@ -71,7 +70,6 @@
     @Mock private lateinit var splitShadeGuidelines: SplitShadeGuidelines
     @Mock private lateinit var aodNotificationIconsSection: AodNotificationIconsSection
     @Mock private lateinit var aodBurnInSection: AodBurnInSection
-    @Mock private lateinit var communalTutorialIndicatorSection: CommunalTutorialIndicatorSection
     @Mock private lateinit var clockSection: ClockSection
     @Mock private lateinit var smartspaceSection: SmartspaceSection
     @Mock private lateinit var keyguardSliceViewSection: KeyguardSliceViewSection
@@ -94,7 +92,6 @@
                 defaultNSSLSection,
                 aodNotificationIconsSection,
                 aodBurnInSection,
-                communalTutorialIndicatorSection,
                 clockSection,
                 smartspaceSection,
                 keyguardSliceViewSection,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelTest.kt
index 70d7a5f..feaf06a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelTest.kt
@@ -27,7 +27,7 @@
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.shade.shadeTestUtil
 import com.android.systemui.testKosmos
@@ -79,8 +79,8 @@
 
             kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                 transitionProgress = listOf(0f, 0f, 0.1f, 0.2f, 0.3f, 1f),
-                startValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
-                endValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
+                startValue = kosmos.blurConfig.maxBlurRadiusPx,
+                endValue = kosmos.blurConfig.maxBlurRadiusPx,
                 checkInterpolatedValues = false,
                 transitionFactory = ::step,
                 actualValuesProvider = { values },
@@ -95,8 +95,8 @@
 
             kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                 transitionProgress = listOf(0f, 0f, 0.1f, 0.2f, 0.3f, 1f),
-                startValue = PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS,
-                endValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
+                startValue = kosmos.blurConfig.minBlurRadiusPx,
+                endValue = kosmos.blurConfig.maxBlurRadiusPx,
                 transitionFactory = ::step,
                 actualValuesProvider = { values },
             )
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModelTest.kt
index 0f239e8..4936f85 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModelTest.kt
@@ -21,7 +21,7 @@
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -44,8 +44,8 @@
 
             kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                 transitionProgress = listOf(0.0f, 0.0f, 0.3f, 0.4f, 0.5f, 1.0f),
-                startValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
-                endValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
+                startValue = kosmos.blurConfig.maxBlurRadiusPx,
+                endValue = kosmos.blurConfig.maxBlurRadiusPx,
                 transitionFactory = { value, state ->
                     TransitionStep(
                         from = KeyguardState.AOD,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerWindowBlurTestUtilKosmos.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerWindowBlurTestUtilKosmos.kt
index c3f0deb..cde8531 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerWindowBlurTestUtilKosmos.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerWindowBlurTestUtilKosmos.kt
@@ -70,6 +70,7 @@
         if (checkInterpolatedValues) {
             assertThat(actualValuesProvider.invoke())
                 .containsExactly(*transitionProgress.map(interpolationFunction).toTypedArray())
+                .inOrder()
         } else {
             assertThat(actualValuesProvider.invoke()).contains(endValue)
         }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelTest.kt
index 7a68d4e..0d48750 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelTest.kt
@@ -26,7 +26,7 @@
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
@@ -78,8 +78,8 @@
 
             kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                 transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
-                startValue = PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS,
-                endValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
+                startValue = kosmos.blurConfig.minBlurRadiusPx,
+                endValue = kosmos.blurConfig.maxBlurRadiusPx,
                 actualValuesProvider = { values },
                 transitionFactory = ::step,
             )
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModelTest.kt
new file mode 100644
index 0000000..88fd333
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModelTest.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 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.keyguard.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.ui.transitions.blurConfig
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@ExperimentalCoroutinesApi
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class GlanceableHubToPrimaryBouncerTransitionViewModelTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val underTest by lazy { kosmos.glanceableHubToPrimaryBouncerTransitionViewModel }
+
+    @Test
+    @DisableSceneContainer
+    fun blurBecomesMaxValueImmediately() =
+        testScope.runTest {
+            val values by collectValues(underTest.windowBlurRadius)
+
+            kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
+                transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
+                startValue = kosmos.blurConfig.maxBlurRadiusPx,
+                endValue = kosmos.blurConfig.maxBlurRadiusPx,
+                actualValuesProvider = { values },
+                transitionFactory = { step, transitionState ->
+                    TransitionStep(
+                        from = KeyguardState.GLANCEABLE_HUB,
+                        to = KeyguardState.PRIMARY_BOUNCER,
+                        value = step,
+                        transitionState = transitionState,
+                        ownerName = "GlanceableHubToPrimaryBouncerTransitionViewModelTest",
+                    )
+                },
+                checkInterpolatedValues = false,
+            )
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
index 6f7e9d3..e4eb55b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
@@ -26,9 +26,7 @@
 import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.DisableSceneContainer
-import com.android.systemui.flags.Flags
 import com.android.systemui.flags.andSceneContainer
-import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.keyguard.data.repository.fakeKeyguardClockRepository
 import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository
 import com.android.systemui.keyguard.shared.model.ClockSize
@@ -77,7 +75,6 @@
     @Before
     fun setup() {
         with(kosmos) {
-            fakeFeatureFlagsClassic.set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, true)
             shadeRepository.setShadeLayoutWide(false)
             underTest = lockscreenContentViewModel
             underTest.activateIn(testScope)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
index fba3997..d909c5a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
@@ -32,7 +32,7 @@
 import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.data.repository.sceneContainerRepository
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
@@ -161,8 +161,8 @@
 
             kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                 transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
-                startValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
-                endValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
+                startValue = kosmos.blurConfig.maxBlurRadiusPx,
+                endValue = kosmos.blurConfig.maxBlurRadiusPx,
                 actualValuesProvider = { values },
                 transitionFactory = ::step,
                 checkInterpolatedValues = false,
@@ -178,8 +178,8 @@
 
             kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                 transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
-                startValue = PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS,
-                endValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
+                startValue = kosmos.blurConfig.minBlurRadiusPx,
+                endValue = kosmos.blurConfig.maxBlurRadiusPx,
                 actualValuesProvider = { values },
                 transitionFactory = ::step,
             )
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModelTest.kt
new file mode 100644
index 0000000..e11e307
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModelTest.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 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.keyguard.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.ui.transitions.blurConfig
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@ExperimentalCoroutinesApi
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class OccludedToPrimaryBouncerTransitionViewModelTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val underTest by lazy { kosmos.occludedToPrimaryBouncerTransitionViewModel }
+
+    @Test
+    @DisableSceneContainer
+    fun blurBecomesMaxValueImmediately() =
+        testScope.runTest {
+            val values by collectValues(underTest.windowBlurRadius)
+
+            kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
+                transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
+                startValue = kosmos.blurConfig.maxBlurRadiusPx,
+                endValue = kosmos.blurConfig.maxBlurRadiusPx,
+                actualValuesProvider = { values },
+                transitionFactory = { step, transitionState ->
+                    TransitionStep(
+                        from = KeyguardState.OCCLUDED,
+                        to = KeyguardState.PRIMARY_BOUNCER,
+                        value = step,
+                        transitionState = transitionState,
+                        ownerName = "OccludedToPrimaryBouncerTransitionViewModelTest",
+                    )
+                },
+                checkInterpolatedValues = false,
+            )
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelTest.kt
index b406e6c..6895794 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelTest.kt
@@ -27,7 +27,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
@@ -141,17 +141,16 @@
         }
 
     @Test
-    fun blurRadiusGoesToMinImmediately() =
+    fun blurRadiusGoesFromMaxToMin() =
         testScope.runTest {
             val values by collectValues(underTest.windowBlurRadius)
 
             kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                 transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
-                startValue = PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS,
-                endValue = PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS,
+                startValue = kosmos.blurConfig.maxBlurRadiusPx,
+                endValue = kosmos.blurConfig.minBlurRadiusPx,
                 actualValuesProvider = { values },
                 transitionFactory = ::step,
-                checkInterpolatedValues = false,
             )
         }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelTest.kt
index a8f0f2f..4013c70 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelTest.kt
@@ -30,7 +30,7 @@
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
@@ -130,11 +130,10 @@
 
             kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                 transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
-                startValue = PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS,
-                endValue = PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS,
+                startValue = kosmos.blurConfig.maxBlurRadiusPx,
+                endValue = kosmos.blurConfig.minBlurRadiusPx,
                 actualValuesProvider = { values },
                 transitionFactory = ::step,
-                checkInterpolatedValues = false,
             )
         }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModelTest.kt
index 2c6e553..f3f4c89 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModelTest.kt
@@ -23,7 +23,7 @@
 import com.android.systemui.flags.DisableSceneContainer
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -47,8 +47,8 @@
 
             kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                 transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
-                startValue = PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS,
-                endValue = PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS,
+                startValue = kosmos.blurConfig.minBlurRadiusPx,
+                endValue = kosmos.blurConfig.minBlurRadiusPx,
                 actualValuesProvider = { values },
                 transitionFactory = { step, transitionState ->
                     TransitionStep(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt
index 9e5976f..bae49fa 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt
@@ -27,7 +27,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
 import com.google.common.collect.Range
@@ -120,8 +120,8 @@
 
             kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                 transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
-                startValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
-                endValue = PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS,
+                startValue = kosmos.blurConfig.maxBlurRadiusPx,
+                endValue = kosmos.blurConfig.minBlurRadiusPx,
                 actualValuesProvider = { values },
                 transitionFactory = ::step,
             )
@@ -135,8 +135,8 @@
 
             kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                 transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
-                startValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
-                endValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
+                startValue = kosmos.blurConfig.maxBlurRadiusPx,
+                endValue = kosmos.blurConfig.maxBlurRadiusPx,
                 actualValuesProvider = { values },
                 transitionFactory = ::step,
                 checkInterpolatedValues = false,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModelTest.kt
new file mode 100644
index 0000000..8a2fc56
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModelTest.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 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.keyguard.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.ui.transitions.blurConfig
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@ExperimentalCoroutinesApi
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class PrimaryBouncerToOccludedTransitionViewModelTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val underTest by lazy { kosmos.primaryBouncerToOccludedTransitionViewModel }
+
+    @Test
+    @DisableSceneContainer
+    fun blurBecomesMaxValueImmediately() =
+        testScope.runTest {
+            val values by collectValues(underTest.windowBlurRadius)
+
+            kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
+                transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
+                startValue = kosmos.blurConfig.minBlurRadiusPx,
+                endValue = kosmos.blurConfig.minBlurRadiusPx,
+                actualValuesProvider = { values },
+                transitionFactory = { step, transitionState ->
+                    TransitionStep(
+                        from = KeyguardState.PRIMARY_BOUNCER,
+                        to = KeyguardState.OCCLUDED,
+                        value = step,
+                        transitionState = transitionState,
+                        ownerName = "PrimaryBouncerToOccludedTransitionViewModelTest",
+                    )
+                },
+                checkInterpolatedValues = false,
+            )
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryTest.kt
index f8f6fe2..466c9f9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactoryTest.kt
@@ -26,6 +26,7 @@
 import androidx.media3.session.CommandButton
 import androidx.media3.session.MediaController as Media3Controller
 import androidx.media3.session.SessionCommand
+import androidx.media3.session.SessionResult
 import androidx.media3.session.SessionToken
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -41,6 +42,8 @@
 import com.android.systemui.util.concurrency.execution
 import com.google.common.collect.ImmutableList
 import com.google.common.truth.Truth.assertThat
+import com.google.common.util.concurrent.ListenableFuture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -60,6 +63,7 @@
 private const val CUSTOM_ACTION_NAME = "Custom Action"
 private const val CUSTOM_ACTION_COMMAND = "custom-action"
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWithLooper
 @RunWith(AndroidJUnit4::class)
@@ -84,12 +88,14 @@
                 }
         }
     private val customLayout = ImmutableList.of<CommandButton>()
+    private val customCommandFuture = mock<ListenableFuture<SessionResult>>()
     private val media3Controller =
         mock<Media3Controller> {
             on { customLayout } doReturn customLayout
             on { sessionExtras } doReturn Bundle()
             on { isCommandAvailable(any()) } doReturn true
             on { isSessionCommandAvailable(any<SessionCommand>()) } doReturn true
+            on { sendCustomCommand(any(), any()) } doReturn customCommandFuture
         }
 
     private lateinit var underTest: Media3ActionFactory
@@ -105,7 +111,7 @@
                 kosmos.mediaLogger,
                 kosmos.looper,
                 handler,
-                kosmos.testScope,
+                testScope,
                 kosmos.execution,
             )
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt
index 77be8c7..6ec38ba 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt
@@ -16,8 +16,9 @@
 
 package com.android.systemui.mediarouter.data.repository
 
-import androidx.test.filters.SmallTest
+import android.media.projection.StopReason
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.Kosmos
@@ -101,7 +102,7 @@
                 origin = CastDevice.CastOrigin.MediaRouter,
             )
 
-        underTest.stopCasting(device)
+        underTest.stopCasting(device, StopReason.STOP_UNKNOWN)
 
         assertThat(castController.lastStoppedDevice).isEqualTo(device)
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/external/ui/viewmodel/TileRequestDialogViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/external/ui/viewmodel/TileRequestDialogViewModelTest.kt
index 369975a..3029928 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/external/ui/viewmodel/TileRequestDialogViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/external/ui/viewmodel/TileRequestDialogViewModelTest.kt
@@ -89,7 +89,7 @@
                 expect.that(state).isEqualTo(expectedState.state)
                 expect.that(handlesLongClick).isFalse()
                 expect.that(handlesSecondaryClick).isFalse()
-                expect.that(icon.get()).isEqualTo(defaultIcon)
+                expect.that(icon).isEqualTo(defaultIcon)
                 expect.that(sideDrawable).isNull()
                 expect.that(accessibilityUiState).isEqualTo(expectedState.accessibilityUiState)
             }
@@ -112,7 +112,7 @@
                 expect.that(state).isEqualTo(expectedState.state)
                 expect.that(handlesLongClick).isFalse()
                 expect.that(handlesSecondaryClick).isFalse()
-                expect.that(icon.get()).isEqualTo(QSTileImpl.DrawableIcon(loadedDrawable))
+                expect.that(icon).isEqualTo(QSTileImpl.DrawableIcon(loadedDrawable))
                 expect.that(sideDrawable).isNull()
                 expect.that(accessibilityUiState).isEqualTo(expectedState.accessibilityUiState)
             }
@@ -135,7 +135,7 @@
             underTest.activateIn(testScope)
             runCurrent()
 
-            assertThat(underTest.uiState.icon.get()).isEqualTo(defaultIcon)
+            assertThat(underTest.uiState.icon).isEqualTo(defaultIcon)
         }
 
     companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiStateTest.kt
index b144f06..9c8e322 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiStateTest.kt
@@ -18,6 +18,7 @@
 
 import android.content.res.Resources
 import android.content.res.mainResources
+import android.graphics.drawable.TestStubDrawable
 import android.service.quicksettings.Tile
 import android.widget.Button
 import android.widget.Switch
@@ -26,9 +27,12 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tileimpl.QSTileImpl.ResourceIcon
 import com.android.systemui.res.R
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
+import java.util.function.Supplier
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -263,6 +267,45 @@
             .contains(resources.getString(R.string.tile_unavailable))
     }
 
+    @Test
+    fun iconAndSupplier_prefersIcon() {
+        val state =
+            QSTile.State().apply {
+                icon = ResourceIcon.get(R.drawable.android)
+                iconSupplier = Supplier { QSTileImpl.DrawableIcon(TestStubDrawable()) }
+            }
+        val uiState = state.toUiState()
+
+        assertThat(uiState.icon).isEqualTo(state.icon)
+    }
+
+    @Test
+    fun iconOnly_hasIcon() {
+        val state = QSTile.State().apply { icon = ResourceIcon.get(R.drawable.android) }
+        val uiState = state.toUiState()
+
+        assertThat(uiState.icon).isEqualTo(state.icon)
+    }
+
+    @Test
+    fun supplierOnly_hasIcon() {
+        val state =
+            QSTile.State().apply {
+                iconSupplier = Supplier { ResourceIcon.get(R.drawable.android) }
+            }
+        val uiState = state.toUiState()
+
+        assertThat(uiState.icon).isEqualTo(state.iconSupplier.get())
+    }
+
+    @Test
+    fun noIconOrSupplier_iconNull() {
+        val state = QSTile.State()
+        val uiState = state.toUiState()
+
+        assertThat(uiState.icon).isNull()
+    }
+
     private fun QSTile.State.toUiState() = toUiState(resources)
 }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/QSSettingsPackageRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/QSSettingsPackageRepositoryTest.kt
new file mode 100644
index 0000000..765c02a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/QSSettingsPackageRepositoryTest.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2024 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.qs.shared
+
+import android.content.Context
+import android.content.Intent
+import android.content.pm.ActivityInfo
+import android.content.pm.PackageManager
+import android.content.pm.ResolveInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.fakeUserRepository
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.anyInt
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import org.mockito.kotlin.whenever
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class QSSettingsPackageRepositoryTest : SysuiTestCase() {
+
+    @get:Rule val mockito: MockitoRule = MockitoJUnit.rule()
+
+    @Mock private lateinit var context: Context
+    @Mock private lateinit var packageManager: PackageManager
+    @Mock private lateinit var resolveInfo: ResolveInfo
+    @Mock private lateinit var activityInfo: ActivityInfo
+
+    private val kosmos = testKosmos()
+    private val scope = kosmos.testScope
+    private val userRepository = kosmos.fakeUserRepository
+
+    private lateinit var underTest: QSSettingsPackageRepository
+
+    @Before
+    fun setUp() {
+        whenever(context.createContextAsUser(any(), anyInt())).thenReturn(context)
+        whenever(context.packageManager).thenReturn(packageManager)
+        whenever(packageManager.queryIntentActivities(any(Intent::class.java), anyInt()))
+            .thenReturn(listOf(resolveInfo))
+        resolveInfo.activityInfo = activityInfo
+
+        underTest = QSSettingsPackageRepository(context, scope, userRepository)
+    }
+
+    @Test
+    fun getSettingsPackageName_noInit_returnsDefaultPackageName() {
+        assertThat(underTest.getSettingsPackageName()).isEqualTo(DEFAULT_SETTINGS_PACKAGE_NAME)
+    }
+
+    @Test
+    fun getSettingsPackageName_repositoryWithCustomPackage_returnsCustomPackageName() {
+        scope.runTest {
+            activityInfo.packageName = CUSTOM_SETTINGS_PACKAGE_NAME
+
+            underTest.init()
+            runCurrent()
+
+            assertThat(underTest.getSettingsPackageName()).isEqualTo(CUSTOM_SETTINGS_PACKAGE_NAME)
+        }
+    }
+
+    @Test
+    fun getSettingsPackageName_noMatchingActivity_returnsDefaultPackageName() {
+        scope.runTest {
+            whenever(packageManager.queryIntentActivities(any(Intent::class.java), anyInt()))
+                .thenReturn(emptyList())
+
+            underTest.init()
+            runCurrent()
+
+            assertThat(underTest.getSettingsPackageName()).isEqualTo(DEFAULT_SETTINGS_PACKAGE_NAME)
+        }
+    }
+
+    @Test
+    fun getSettingsPackageName_nullActivityInfo_returnsDefaultPackageName() {
+        scope.runTest {
+            resolveInfo.activityInfo = null
+
+            underTest.init()
+            runCurrent()
+
+            assertThat(underTest.getSettingsPackageName()).isEqualTo(DEFAULT_SETTINGS_PACKAGE_NAME)
+        }
+    }
+
+    companion object {
+        private const val DEFAULT_SETTINGS_PACKAGE_NAME = "com.android.settings"
+        private const val CUSTOM_SETTINGS_PACKAGE_NAME = "com.android.test.settings"
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CastTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CastTileTest.java
index 9f12b18..31a627f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CastTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/CastTileTest.java
@@ -20,6 +20,7 @@
 import static junit.framework.TestCase.assertEquals;
 
 import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.same;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.mock;
@@ -30,6 +31,7 @@
 import android.media.MediaRouter;
 import android.media.MediaRouter.RouteInfo;
 import android.media.projection.MediaProjectionInfo;
+import android.media.projection.StopReason;
 import android.os.Handler;
 import android.service.quicksettings.Tile;
 import android.testing.TestableLooper;
@@ -336,7 +338,8 @@
         mCastTile.handleClick(null /* view */);
         mTestableLooper.processAllMessages();
 
-        verify(mController, times(1)).stopCasting(same(device));
+        verify(mController, times(1))
+                .stopCasting(same(device), eq(StopReason.STOP_QS_TILE));
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorCorrectionTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorCorrectionTileTest.java
index 028beb5..e5e8d4a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorCorrectionTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorCorrectionTileTest.java
@@ -39,6 +39,7 @@
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.QsEventLogger;
 import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.shared.QSSettingsPackageRepository;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.util.settings.FakeSettings;
 import com.android.systemui.util.settings.SecureSettings;
@@ -55,6 +56,7 @@
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class ColorCorrectionTileTest extends SysuiTestCase {
+    private static final String SETTINGS_PACKAGE_NAME = "com.android.settings";
 
     @Mock
     private QSHost mHost;
@@ -70,6 +72,8 @@
     private QsEventLogger mUiEventLogger;
     @Mock
     private UserTracker mUserTracker;
+    @Mock
+    private QSSettingsPackageRepository mQSSettingsPackageRepository;
 
     private TestableLooper mTestableLooper;
     private SecureSettings mSecureSettings;
@@ -83,6 +87,8 @@
         mTestableLooper = TestableLooper.get(this);
 
         when(mHost.getContext()).thenReturn(mContext);
+        when(mQSSettingsPackageRepository.getSettingsPackageName())
+                .thenReturn(SETTINGS_PACKAGE_NAME);
 
         mTile = new ColorCorrectionTile(
                 mHost,
@@ -95,7 +101,8 @@
                 mActivityStarter,
                 mQSLogger,
                 mUserTracker,
-                mSecureSettings
+                mSecureSettings,
+                mQSSettingsPackageRepository
         );
 
         mTile.initialize();
@@ -119,5 +126,6 @@
                 anyInt(), any());
         assertThat(IntentCaptor.getValue().getAction()).isEqualTo(
                 Settings.ACTION_COLOR_CORRECTION_SETTINGS);
+        assertThat(IntentCaptor.getValue().getPackage()).isEqualTo(SETTINGS_PACKAGE_NAME);
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
index a58dd63..cbde998 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ColorInversionTileTest.java
@@ -45,6 +45,7 @@
 import com.android.systemui.qs.QsEventLogger;
 import com.android.systemui.qs.flags.QsInCompose;
 import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.shared.QSSettingsPackageRepository;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.res.R;
 import com.android.systemui.settings.UserTracker;
@@ -59,15 +60,16 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.util.List;
-
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
 import platform.test.runner.parameterized.Parameters;
 
+import java.util.List;
+
 @RunWith(ParameterizedAndroidJunit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class ColorInversionTileTest extends SysuiTestCase {
+    private static final String SETTINGS_PACKAGE_NAME = "com.android.settings";
     private static final Integer COLOR_INVERSION_DISABLED = 0;
     private static final Integer COLOR_INVERSION_ENABLED = 1;
 
@@ -90,6 +92,8 @@
     private QsEventLogger mUiEventLogger;
     @Mock
     private UserTracker mUserTracker;
+    @Mock
+    private QSSettingsPackageRepository mQSSettingsPackageRepository;
 
     private TestableLooper mTestableLooper;
     private SecureSettings mSecureSettings;
@@ -108,6 +112,8 @@
         mTestableLooper = TestableLooper.get(this);
 
         when(mHost.getContext()).thenReturn(mContext);
+        when(mQSSettingsPackageRepository.getSettingsPackageName())
+                .thenReturn(SETTINGS_PACKAGE_NAME);
 
         mTile = new ColorInversionTile(
                 mHost,
@@ -120,7 +126,8 @@
                 mActivityStarter,
                 mQSLogger,
                 mUserTracker,
-                mSecureSettings
+                mSecureSettings,
+                mQSSettingsPackageRepository
         );
 
         mTile.initialize();
@@ -144,6 +151,7 @@
                 anyInt(), any());
         assertThat(IntentCaptor.getValue().getAction()).isEqualTo(
                 Settings.ACTION_COLOR_INVERSION_SETTINGS);
+        assertThat(IntentCaptor.getValue().getPackage()).isEqualTo(SETTINGS_PACKAGE_NAME);
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt
index c854920..ae4da9d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt
@@ -32,11 +32,10 @@
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
 import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.shared.QSSettingsPackageRepository
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.statusbar.policy.KeyguardStateController
 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.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
@@ -49,8 +48,10 @@
 import org.mockito.Mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.whenever
 
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -68,21 +69,24 @@
     @Mock private lateinit var dialog: SystemUIDialog
     @Mock private lateinit var expandable: Expandable
     @Mock private lateinit var controller: DialogTransitionAnimator.Controller
+    @Mock private lateinit var settingsPackageRepository: QSSettingsPackageRepository
+
+    @Captor private lateinit var argumentCaptor: ArgumentCaptor<Runnable>
 
     private lateinit var testableLooper: TestableLooper
     private lateinit var systemClock: FakeSystemClock
     private lateinit var backgroundDelayableExecutor: FakeExecutor
     private lateinit var fontScalingTile: FontScalingTile
 
-    @Captor private lateinit var argumentCaptor: ArgumentCaptor<Runnable>
-
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
         testableLooper = TestableLooper.get(this)
-        `when`(qsHost.getContext()).thenReturn(mContext)
-        `when`(fontScalingDialogDelegate.createDialog()).thenReturn(dialog)
-        `when`(expandable.dialogTransitionController(any())).thenReturn(controller)
+        whenever(qsHost.getContext()).thenReturn(mContext)
+        whenever(fontScalingDialogDelegate.createDialog()).thenReturn(dialog)
+        whenever(expandable.dialogTransitionController(any())).thenReturn(controller)
+        whenever(settingsPackageRepository.getSettingsPackageName())
+            .thenReturn(SETTINGS_PACKAGE_NAME)
         systemClock = FakeSystemClock()
         backgroundDelayableExecutor = FakeExecutor(systemClock)
 
@@ -100,6 +104,7 @@
                 keyguardStateController,
                 mDialogTransitionAnimator,
                 { fontScalingDialogDelegate },
+                settingsPackageRepository,
             )
         fontScalingTile.initialize()
         testableLooper.processAllMessages()
@@ -120,7 +125,7 @@
 
     @Test
     fun clickTile_screenUnlocked_showDialogAnimationFromView() {
-        `when`(keyguardStateController.isShowing).thenReturn(false)
+        whenever(keyguardStateController.isShowing).thenReturn(false)
         fontScalingTile.click(expandable)
         testableLooper.processAllMessages()
 
@@ -130,7 +135,7 @@
                 eq(null),
                 eq(true),
                 eq(true),
-                eq(false)
+                eq(false),
             )
         argumentCaptor.value.run()
         verify(mDialogTransitionAnimator).show(any(), any(), anyBoolean())
@@ -138,7 +143,7 @@
 
     @Test
     fun clickTile_onLockScreen_neverShowDialogAnimationFromView() {
-        `when`(keyguardStateController.isShowing).thenReturn(true)
+        whenever(keyguardStateController.isShowing).thenReturn(true)
         fontScalingTile.click(expandable)
         testableLooper.processAllMessages()
 
@@ -148,7 +153,7 @@
                 eq(null),
                 eq(true),
                 eq(true),
-                eq(false)
+                eq(false),
             )
         argumentCaptor.value.run()
         verify(mDialogTransitionAnimator, never()).show(any(), any(), anyBoolean())
@@ -159,5 +164,10 @@
         val intent: Intent? = fontScalingTile.getLongClickIntent()
 
         assertThat(intent!!.action).isEqualTo(Settings.ACTION_TEXT_READING_SETTINGS)
+        assertThat(intent.getPackage()).isEqualTo(SETTINGS_PACKAGE_NAME)
+    }
+
+    companion object {
+        private const val SETTINGS_PACKAGE_NAME = "com.android.settings"
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
index 0fd7c98..fc1d73b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
@@ -27,11 +27,13 @@
 import static org.junit.Assert.assertFalse;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.Dialog;
+import android.media.projection.StopReason;
 import android.os.Handler;
 import android.platform.test.flag.junit.FlagsParameterization;
 import android.service.quicksettings.Tile;
@@ -234,7 +236,7 @@
 
         mTile.handleClick(null /* view */);
 
-        verify(mController, times(1)).stopRecording();
+        verify(mController, times(1)).stopRecording(eq(StopReason.STOP_QS_TILE));
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java
index 5c6657b..cfbc812 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java
@@ -1,6 +1,6 @@
 package com.android.systemui.qs.tiles.dialog;
 
-import static com.android.systemui.qs.tiles.dialog.InternetDialogController.MAX_WIFI_ENTRY_COUNT;
+import static com.android.systemui.qs.tiles.dialog.InternetDetailsContentController.MAX_WIFI_ENTRY_COUNT;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -63,7 +63,7 @@
     @Mock
     private WifiEntry mWifiEntry;
     @Mock
-    private InternetDialogController mInternetDialogController;
+    private InternetDetailsContentController mInternetDetailsContentController;
     @Mock
     private Drawable mWifiDrawable;
     @Mock
@@ -86,7 +86,7 @@
         when(mWifiEntry.getTitle()).thenReturn(WIFI_TITLE);
         when(mWifiEntry.getSummary(false)).thenReturn(WIFI_SUMMARY);
 
-        mInternetAdapter = new InternetAdapter(mInternetDialogController, mScope);
+        mInternetAdapter = new InternetAdapter(mInternetDetailsContentController, mScope);
         mViewHolder = mInternetAdapter.onCreateViewHolder(new LinearLayout(mContext), 0);
         mInternetAdapter.setWifiEntries(Arrays.asList(mWifiEntry), 1 /* wifiEntriesCount */);
     }
@@ -124,7 +124,7 @@
 
     @Test
     public void onBindViewHolder_getWifiDrawableNull_noCrash() {
-        when(mInternetDialogController.getWifiDrawable(any())).thenReturn(null);
+        when(mInternetDetailsContentController.getWifiDrawable(any())).thenReturn(null);
 
         mInternetAdapter.onBindViewHolder(mViewHolder, 0);
 
@@ -133,7 +133,7 @@
 
     @Test
     public void onBindViewHolder_getWifiDrawableNotNull_setWifiIconDrawable() {
-        when(mInternetDialogController.getWifiDrawable(any())).thenReturn(mWifiDrawable);
+        when(mInternetDetailsContentController.getWifiDrawable(any())).thenReturn(mWifiDrawable);
 
         mInternetAdapter.onBindViewHolder(mViewHolder, 0);
 
@@ -232,7 +232,7 @@
 
         mViewHolder.onWifiClick(mWifiEntry, mock(View.class));
 
-        verify(mInternetDialogController).startActivityForDialog(any());
+        verify(mInternetDetailsContentController).startActivityForDialog(any());
         verify(mSpyContext, never()).startActivity(any());
     }
 
@@ -242,7 +242,7 @@
 
         mViewHolder.onWifiClick(mWifiEntry, mock(View.class));
 
-        verify(mInternetDialogController).connect(mWifiEntry);
+        verify(mInternetDetailsContentController).connect(mWifiEntry);
     }
 
     @Test
@@ -252,7 +252,7 @@
 
         mViewHolder.onWifiClick(mWifiEntry, mock(View.class));
 
-        verify(mInternetDialogController).launchWifiDetailsSetting(anyString(), any());
+        verify(mInternetDetailsContentController).launchWifiDetailsSetting(anyString(), any());
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileUserActionInteractorTest.kt
index 3bc53b27..0cf3734 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileUserActionInteractorTest.kt
@@ -23,29 +23,45 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.accessibility.data.repository.FakeColorCorrectionRepository
+import com.android.systemui.qs.shared.QSSettingsPackageRepository
 import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
 import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
 import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
+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 org.mockito.kotlin.whenever
 
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
 class ColorCorrectionTileUserActionInteractorTest : SysuiTestCase() {
 
+    @get:Rule val mockito: MockitoRule = MockitoJUnit.rule()
+
+    @Mock private lateinit var settingsPackageRepository: QSSettingsPackageRepository
+
     private val testUser = UserHandle.CURRENT
     private val repository = FakeColorCorrectionRepository()
     private val inputHandler = FakeQSTileIntentUserInputHandler()
 
-    private val underTest =
-        ColorCorrectionUserActionInteractor(
-            repository,
-            inputHandler,
-        )
+    private lateinit var underTest: ColorCorrectionUserActionInteractor
+
+    @Before
+    fun setUp() {
+        whenever(settingsPackageRepository.getSettingsPackageName())
+            .thenReturn(SETTINGS_PACKAGE_NAME)
+
+        underTest =
+            ColorCorrectionUserActionInteractor(repository, inputHandler, settingsPackageRepository)
+    }
 
     @Test
     fun handleClickWhenEnabled() = runTest {
@@ -86,6 +102,11 @@
 
         QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
             assertThat(it.intent.action).isEqualTo(Settings.ACTION_COLOR_CORRECTION_SETTINGS)
+            assertThat(it.intent.getPackage()).isEqualTo(SETTINGS_PACKAGE_NAME)
         }
     }
+
+    companion object {
+        private const val SETTINGS_PACKAGE_NAME = "com.android.settings"
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingUserActionInteractorTest.kt
index d309554..9bd4895 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingUserActionInteractorTest.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.qs.shared.QSSettingsPackageRepository
 import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
 import com.android.systemui.qs.tiles.base.actions.intentInputs
 import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
@@ -36,11 +37,7 @@
 import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel
 import com.android.systemui.statusbar.phone.FakeKeyguardStateController
 import com.android.systemui.statusbar.phone.SystemUIDialog
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
-import com.google.common.truth.Truth
+import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -51,15 +48,14 @@
 import org.mockito.Mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FontScalingUserActionInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
-    private val qsTileIntentUserActionHandler = FakeQSTileIntentUserInputHandler()
-    private val keyguardStateController = FakeKeyguardStateController()
-
-    private lateinit var underTest: FontScalingTileUserActionInteractor
 
     @Mock private lateinit var fontScalingDialogDelegate: FontScalingDialogDelegate
     @Mock private lateinit var mDialogTransitionAnimator: DialogTransitionAnimator
@@ -67,35 +63,47 @@
     @Mock private lateinit var activityStarter: ActivityStarter
     @Mock private lateinit var expandable: Expandable
     @Mock private lateinit var controller: DialogTransitionAnimator.Controller
+    @Mock private lateinit var settingsPackageRepository: QSSettingsPackageRepository
 
     @Captor private lateinit var argumentCaptor: ArgumentCaptor<Runnable>
 
+    private val kosmos = Kosmos()
+    private val scope = kosmos.testScope
+    private val qsTileIntentUserActionHandler = FakeQSTileIntentUserInputHandler()
+    private val keyguardStateController = FakeKeyguardStateController()
+
+    private lateinit var underTest: FontScalingTileUserActionInteractor
+
     @Before
     fun setup() {
         activityStarter = mock<ActivityStarter>()
         mDialogTransitionAnimator = mock<DialogTransitionAnimator>()
         dialog = mock<SystemUIDialog>()
-        fontScalingDialogDelegate =
-            mock<FontScalingDialogDelegate> { whenever(createDialog()).thenReturn(dialog) }
+        fontScalingDialogDelegate = mock<FontScalingDialogDelegate>()
+        whenever(fontScalingDialogDelegate.createDialog()).thenReturn(dialog)
         controller = mock<DialogTransitionAnimator.Controller>()
-        expandable =
-            mock<Expandable> { whenever(dialogTransitionController(any())).thenReturn(controller) }
+        expandable = mock<Expandable>()
+        whenever(expandable.dialogTransitionController(any())).thenReturn(controller)
+        settingsPackageRepository = mock<QSSettingsPackageRepository>()
+        whenever(settingsPackageRepository.getSettingsPackageName())
+            .thenReturn(SETTINGS_PACKAGE_NAME)
         argumentCaptor = ArgumentCaptor.forClass(Runnable::class.java)
 
         underTest =
             FontScalingTileUserActionInteractor(
-                kosmos.testScope.coroutineContext,
+                scope.coroutineContext,
                 qsTileIntentUserActionHandler,
                 { fontScalingDialogDelegate },
                 keyguardStateController,
                 mDialogTransitionAnimator,
-                activityStarter
+                activityStarter,
+                settingsPackageRepository,
             )
     }
 
     @Test
     fun clickTile_screenUnlocked_showDialogAnimationFromView() =
-        kosmos.testScope.runTest {
+        scope.runTest {
             keyguardStateController.isShowing = false
 
             underTest.handleInput(click(FontScalingTileModel, expandable = expandable))
@@ -106,7 +114,7 @@
                     eq(null),
                     eq(true),
                     eq(true),
-                    eq(false)
+                    eq(false),
                 )
             argumentCaptor.value.run()
             verify(mDialogTransitionAnimator).show(any(), any(), anyBoolean())
@@ -114,7 +122,7 @@
 
     @Test
     fun clickTile_onLockScreen_neverShowDialogAnimationFromView_butShowsDialog() =
-        kosmos.testScope.runTest {
+        scope.runTest {
             keyguardStateController.isShowing = true
 
             underTest.handleInput(click(FontScalingTileModel, expandable = expandable))
@@ -125,7 +133,7 @@
                     eq(null),
                     eq(true),
                     eq(true),
-                    eq(false)
+                    eq(false),
                 )
             argumentCaptor.value.run()
             verify(mDialogTransitionAnimator, never()).show(any(), any(), anyBoolean())
@@ -134,17 +142,20 @@
 
     @Test
     fun handleLongClick() =
-        kosmos.testScope.runTest {
+        scope.runTest {
             underTest.handleInput(QSTileInputTestKtx.longClick(FontScalingTileModel))
 
-            Truth.assertThat(qsTileIntentUserActionHandler.handledInputs).hasSize(1)
-            val intentInput = qsTileIntentUserActionHandler.intentInputs.last()
-            val actualIntentAction = intentInput.intent.action
-            val expectedIntentAction = Settings.ACTION_TEXT_READING_SETTINGS
-            Truth.assertThat(actualIntentAction).isEqualTo(expectedIntentAction)
+            assertThat(qsTileIntentUserActionHandler.handledInputs).hasSize(1)
+            val it = qsTileIntentUserActionHandler.intentInputs.last()
+            assertThat(it.intent.action).isEqualTo(Settings.ACTION_TEXT_READING_SETTINGS)
+            assertThat(it.intent.getPackage()).isEqualTo(SETTINGS_PACKAGE_NAME)
         }
 
     private class FontScalingTileTestView(context: Context) : View(context), LaunchableView {
         override fun setShouldBlockVisibilityChanges(block: Boolean) {}
     }
+
+    companion object {
+        private const val SETTINGS_PACKAGE_NAME = "com.android.settings"
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractorTest.kt
index f574f79..3f77b86 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractorTest.kt
@@ -23,29 +23,45 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.accessibility.data.repository.FakeColorInversionRepository
+import com.android.systemui.qs.shared.QSSettingsPackageRepository
 import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
 import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
 import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
+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 org.mockito.kotlin.whenever
 
 @SmallTest
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
 class ColorInversionUserActionInteractorTest : SysuiTestCase() {
 
+    @get:Rule val mockito: MockitoRule = MockitoJUnit.rule()
+
+    @Mock private lateinit var settingsPackageRepository: QSSettingsPackageRepository
+
     private val testUser = UserHandle.CURRENT
     private val repository = FakeColorInversionRepository()
     private val inputHandler = FakeQSTileIntentUserInputHandler()
 
-    private val underTest =
-        ColorInversionUserActionInteractor(
-            repository,
-            inputHandler,
-        )
+    private lateinit var underTest: ColorInversionUserActionInteractor
+
+    @Before
+    fun setUp() {
+        whenever(settingsPackageRepository.getSettingsPackageName())
+            .thenReturn(SETTINGS_PACKAGE_NAME)
+
+        underTest =
+            ColorInversionUserActionInteractor(repository, inputHandler, settingsPackageRepository)
+    }
 
     @Test
     fun handleClickWhenEnabled() = runTest {
@@ -86,6 +102,11 @@
 
         QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
             assertThat(it.intent.action).isEqualTo(Settings.ACTION_COLOR_INVERSION_SETTINGS)
+            assertThat(it.intent.getPackage()).isEqualTo(SETTINGS_PACKAGE_NAME)
         }
     }
+
+    companion object {
+        private const val SETTINGS_PACKAGE_NAME = "com.android.settings"
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt
index 0b56d7b..778c73f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.qs.tiles.impl.screenrecord.domain.interactor
 
 import android.app.Dialog
+import android.media.projection.StopReason
 import android.os.UserHandle
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -92,7 +93,7 @@
 
         underTest.handleInput(QSTileInputTestKtx.click(recordingModel))
 
-        verify(recordingController).stopRecording()
+        verify(recordingController).stopRecording(eq(StopReason.STOP_QS_TILE))
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt
index 24f6b6d..7ab8ab9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModelTest.kt
@@ -36,6 +36,7 @@
 import com.android.systemui.scene.domain.startable.sceneContainerStartable
 import com.android.systemui.scene.shared.model.Overlays
 import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.shade.shared.flag.DualShade
 import com.android.systemui.testKosmos
@@ -124,6 +125,24 @@
             assertThat(currentOverlays).doesNotContain(Overlays.QuickSettingsShade)
         }
 
+    @Test
+    fun showHeader_showsOnNarrowScreen() =
+        testScope.runTest {
+            kosmos.shadeRepository.setShadeLayoutWide(false)
+            runCurrent()
+
+            assertThat(underTest.showHeader).isTrue()
+        }
+
+    @Test
+    fun showHeader_hidesOnWideScreen() =
+        testScope.runTest {
+            kosmos.shadeRepository.setShadeLayoutWide(true)
+            runCurrent()
+
+            assertThat(underTest.showHeader).isFalse()
+        }
+
     private fun TestScope.lockDevice() {
         val currentScene by collectLastValue(sceneInteractor.currentScene)
         kosmos.powerInteractor.setAsleepForTest()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/RecordingServiceTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
index a6a1d4a..50fa9d2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
@@ -41,6 +41,7 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.content.Intent;
+import android.media.projection.StopReason;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -199,16 +200,16 @@
     public void testOnSystemRequestedStop_recordingInProgress_endsRecording() throws IOException {
         doReturn(true).when(mController).isRecording();
 
-        mRecordingService.onStopped();
+        mRecordingService.onStopped(StopReason.STOP_UNKNOWN);
 
-        verify(mScreenMediaRecorder).end();
+        verify(mScreenMediaRecorder).end(eq(StopReason.STOP_UNKNOWN));
     }
 
     @Test
     public void testOnSystemRequestedStop_recordingInProgress_updatesState() {
         doReturn(true).when(mController).isRecording();
 
-        mRecordingService.onStopped();
+        mRecordingService.onStopped(StopReason.STOP_UNKNOWN);
 
         assertUpdateState(false);
     }
@@ -218,18 +219,18 @@
             throws IOException {
         doReturn(false).when(mController).isRecording();
 
-        mRecordingService.onStopped();
+        mRecordingService.onStopped(StopReason.STOP_UNKNOWN);
 
-        verify(mScreenMediaRecorder, never()).end();
+        verify(mScreenMediaRecorder, never()).end(StopReason.STOP_UNKNOWN);
     }
 
     @Test
     public void testOnSystemRequestedStop_recorderEndThrowsRuntimeException_releasesRecording()
             throws IOException {
         doReturn(true).when(mController).isRecording();
-        doThrow(new RuntimeException()).when(mScreenMediaRecorder).end();
+        doThrow(new RuntimeException()).when(mScreenMediaRecorder).end(StopReason.STOP_UNKNOWN);
 
-        mRecordingService.onStopped();
+        mRecordingService.onStopped(StopReason.STOP_UNKNOWN);
 
         verify(mScreenMediaRecorder).release();
     }
@@ -238,7 +239,7 @@
     public void testOnSystemRequestedStop_whenRecordingInProgress_showsNotifications() {
         doReturn(true).when(mController).isRecording();
 
-        mRecordingService.onStopped();
+        mRecordingService.onStopped(StopReason.STOP_UNKNOWN);
 
         // Processing notification
         ArgumentCaptor<Notification> notifCaptor = ArgumentCaptor.forClass(Notification.class);
@@ -271,9 +272,9 @@
     public void testOnSystemRequestedStop_recorderEndThrowsRuntimeException_showsErrorNotification()
             throws IOException {
         doReturn(true).when(mController).isRecording();
-        doThrow(new RuntimeException()).when(mScreenMediaRecorder).end();
+        doThrow(new RuntimeException()).when(mScreenMediaRecorder).end(anyInt());
 
-        mRecordingService.onStopped();
+        mRecordingService.onStopped(StopReason.STOP_UNKNOWN);
 
         verify(mRecordingService).createErrorSavingNotification(any());
         ArgumentCaptor<Notification> notifCaptor = ArgumentCaptor.forClass(Notification.class);
@@ -289,9 +290,9 @@
     public void testOnSystemRequestedStop_recorderEndThrowsOOMError_releasesRecording()
             throws IOException {
         doReturn(true).when(mController).isRecording();
-        doThrow(new OutOfMemoryError()).when(mScreenMediaRecorder).end();
+        doThrow(new OutOfMemoryError()).when(mScreenMediaRecorder).end(anyInt());
 
-        assertThrows(Throwable.class, () -> mRecordingService.onStopped());
+        assertThrows(Throwable.class, () -> mRecordingService.onStopped(StopReason.STOP_UNKNOWN));
 
         verify(mScreenMediaRecorder).release();
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
index aceea90..ade5941 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.screenrecord.data.repository
 
+import android.media.projection.StopReason
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -31,6 +32,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
@@ -126,8 +128,8 @@
     @Test
     fun stopRecording_invokesController() =
         testScope.runTest {
-            underTest.stopRecording()
+            underTest.stopRecording(StopReason.STOP_PRIVACY_CHIP)
 
-            verify(recordingController).stopRecording()
+            verify(recordingController).stopRecording(eq(StopReason.STOP_PRIVACY_CHIP))
         }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
index 3d3d666..ee9cb14 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -19,6 +19,8 @@
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 import android.testing.TestableLooper.RunWithLooper
+import android.view.Choreographer
+import android.view.MotionEvent
 import android.widget.FrameLayout
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -44,6 +46,7 @@
 import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractor
 import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
 import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
+import com.android.systemui.statusbar.BlurUtils
 import com.android.systemui.statusbar.DragDownHelper
 import com.android.systemui.statusbar.LockscreenShadeTransitionController
 import com.android.systemui.statusbar.NotificationInsetsController
@@ -66,6 +69,7 @@
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.window.ui.viewmodel.WindowRootViewModel
 import com.google.common.truth.Truth.assertThat
 import java.util.Optional
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -91,6 +95,9 @@
 @SmallTest
 class NotificationShadeWindowViewTest : SysuiTestCase() {
 
+    @Mock private lateinit var choreographer: Choreographer
+    @Mock private lateinit var blurUtils: BlurUtils
+    @Mock private lateinit var windowRootViewModelFactory: WindowRootViewModel.Factory
     @Mock private lateinit var dragDownHelper: DragDownHelper
     @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
     @Mock private lateinit var shadeController: ShadeController
@@ -168,6 +175,9 @@
         testScope = TestScope()
         controller =
             NotificationShadeWindowViewController(
+                blurUtils,
+                windowRootViewModelFactory,
+                choreographer,
                 lockscreenShadeTransitionController,
                 FalsingCollectorFake(),
                 statusBarStateController,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/BlurUtilsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
index d0ba629..e7b6e4d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar
 
-import android.content.res.Resources
 import android.view.CrossWindowBlurListeners
 import android.view.SurfaceControl
 import android.view.ViewRootImpl
@@ -24,11 +23,11 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.any
 import org.mockito.Mockito.anyInt
 import org.mockito.Mockito.clearInvocations
@@ -36,13 +35,14 @@
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class BlurUtilsTest : SysuiTestCase() {
 
-    @Mock lateinit var resources: Resources
+    val blurConfig: BlurConfig = BlurConfig(minBlurRadiusPx = 1.0f, maxBlurRadiusPx = 100.0f)
     @Mock lateinit var dumpManager: DumpManager
     @Mock lateinit var transaction: SurfaceControl.Transaction
     @Mock lateinit var crossWindowBlurListeners: CrossWindowBlurListeners
@@ -109,7 +109,7 @@
         verify(transaction).setEarlyWakeupEnd()
     }
 
-    inner class TestableBlurUtils : BlurUtils(resources, crossWindowBlurListeners, dumpManager) {
+    inner class TestableBlurUtils : BlurUtils(blurConfig, crossWindowBlurListeners, dumpManager) {
         var blursEnabled = true
 
         override fun supportsBlursOnWindows(): Boolean {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
index 9f94cff..2d7dc2e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
@@ -17,15 +17,19 @@
 package com.android.systemui.statusbar
 
 import android.os.IBinder
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import android.testing.TestableLooper.RunWithLooper
 import android.view.Choreographer
 import android.view.View
 import android.view.ViewRootImpl
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ShadeInterpolation
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeExpansionChangeEvent
@@ -35,8 +39,10 @@
 import com.android.systemui.statusbar.policy.FakeConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
+import com.android.systemui.testKosmos
 import com.android.systemui.util.WallpaperController
 import com.android.systemui.util.mockito.eq
+import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor
 import com.google.common.truth.Truth.assertThat
 import java.util.function.Consumer
 import org.junit.Before
@@ -44,6 +50,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.floatThat
 import org.mockito.Captor
@@ -63,7 +70,10 @@
 @RunWithLooper
 @SmallTest
 class NotificationShadeDepthControllerTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
 
+    private val applicationScope = kosmos.testScope.backgroundScope
+    @Mock private lateinit var windowRootViewBlurInteractor: WindowRootViewBlurInteractor
     @Mock private lateinit var statusBarStateController: StatusBarStateController
     @Mock private lateinit var blurUtils: BlurUtils
     @Mock private lateinit var biometricUnlockController: BiometricUnlockController
@@ -101,8 +111,8 @@
             answer.arguments[0] as Float / maxBlur.toFloat()
         }
         `when`(blurUtils.supportsBlursOnWindows()).thenReturn(true)
-        `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur)
-        `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur)
+        `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur.toFloat())
+        `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur.toFloat())
 
         notificationShadeDepthController =
             NotificationShadeDepthController(
@@ -115,9 +125,12 @@
                 notificationShadeWindowController,
                 dozeParameters,
                 context,
-                    ResourcesSplitShadeStateController(),
+                ResourcesSplitShadeStateController(),
+                windowRootViewBlurInteractor,
+                applicationScope,
                 dumpManager,
-                configurationController,)
+                configurationController,
+            )
         notificationShadeDepthController.shadeAnimation = shadeAnimation
         notificationShadeDepthController.brightnessMirrorSpring = brightnessSpring
         notificationShadeDepthController.root = root
@@ -309,8 +322,8 @@
         `when`(blurUtils.ratioOfBlurRadius(anyFloat())).then { answer ->
             answer.arguments[0] as Float / maxBlur.toFloat()
         }
-        `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur)
-        `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur)
+        `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur.toFloat())
+        `when`(blurUtils.maxBlurRadius).thenReturn(maxBlur.toFloat())
 
         notificationShadeDepthController.transitionToFullShadeProgress = 1f
         notificationShadeDepthController.updateBlurCallback.doFrame(0)
@@ -356,6 +369,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_BOUNCER_UI_REVAMP)
     fun ignoreShadeBlurUntilHidden_schedulesFrame() {
         notificationShadeDepthController.blursDisabledForAppLaunch = true
         verify(blurUtils).prepareBlur(any(), anyInt())
@@ -364,6 +378,13 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_BOUNCER_UI_REVAMP)
+    fun ignoreShadeBlurUntilHidden_requestsBlur_windowBlurFlag() {
+        notificationShadeDepthController.blursDisabledForAppLaunch = true
+        verify(windowRootViewBlurInteractor).requestBlurForShade(anyInt(), anyBoolean())
+    }
+
+    @Test
     fun ignoreBlurForUnlock_ignores() {
         notificationShadeDepthController.onPanelExpansionChanged(
             ShadeExpansionChangeEvent(
@@ -410,6 +431,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_BOUNCER_UI_REVAMP)
     fun brightnessMirror_hidesShadeBlur() {
         // Brightness mirror is fully visible
         `when`(brightnessSpring.ratio).thenReturn(1f)
@@ -427,6 +449,23 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_BOUNCER_UI_REVAMP)
+    fun brightnessMirror_hidesShadeBlur_withWindowBlurFlag() {
+        // Brightness mirror is fully visible
+        `when`(brightnessSpring.ratio).thenReturn(1f)
+        // And shade is blurred
+        notificationShadeDepthController.onPanelExpansionChanged(
+            ShadeExpansionChangeEvent(fraction = 1f, expanded = true, tracking = false)
+        )
+        `when`(shadeAnimation.radius).thenReturn(maxBlur.toFloat())
+
+        notificationShadeDepthController.updateBlurCallback.doFrame(0)
+        verify(notificationShadeWindowController).setBackgroundBlurRadius(eq(0))
+        verify(wallpaperController).setNotificationShadeZoom(eq(1f))
+        verify(windowRootViewBlurInteractor).requestBlurForShade(0, false)
+    }
+
+    @Test
     fun ignoreShadeBlurUntilHidden_whennNull_ignoresIfShadeHasNoBlur() {
         `when`(shadeAnimation.radius).thenReturn(0f)
         notificationShadeDepthController.blursDisabledForAppLaunch = true
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
index 40f13bb..17076b4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt
@@ -306,12 +306,13 @@
 
     @Test
     @EnableFlags(FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY)
-    fun chips_basicTime_hiddenIfAutomaticallyPromoted() =
+    fun chips_basicTime_timeHiddenIfAutomaticallyPromoted() =
         kosmos.runTest {
             val latest by collectLastValue(underTest.chips)
 
             val promotedContentBuilder =
                 PromotedNotificationContentModel.Builder("notif").apply {
+                    this.wasPromotedAutomatically = true
                     this.time =
                         PromotedNotificationContentModel.When(
                             time = 6543L,
@@ -334,6 +335,36 @@
         }
 
     @Test
+    @EnableFlags(FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY)
+    fun chips_basicTime_timeShownIfNotAutomaticallyPromoted() =
+        kosmos.runTest {
+            val latest by collectLastValue(underTest.chips)
+
+            val promotedContentBuilder =
+                PromotedNotificationContentModel.Builder("notif").apply {
+                    this.wasPromotedAutomatically = false
+                    this.time =
+                        PromotedNotificationContentModel.When(
+                            time = 6543L,
+                            mode = PromotedNotificationContentModel.When.Mode.BasicTime,
+                        )
+                }
+            setNotifs(
+                listOf(
+                    activeNotificationModel(
+                        key = "notif",
+                        statusBarChipIcon = mock<StatusBarIconView>(),
+                        promotedContent = promotedContentBuilder.build(),
+                    )
+                )
+            )
+
+            assertThat(latest).hasSize(1)
+            assertThat(latest!![0])
+                .isInstanceOf(OngoingActivityChipModel.Shown.ShortTimeDelta::class.java)
+        }
+
+    @Test
     @DisableFlags(FLAG_PROMOTE_NOTIFICATIONS_AUTOMATICALLY)
     fun chips_basicTime_isShortTimeDelta() =
         kosmos.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/compose/ChronometerStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/compose/ChronometerStateTest.kt
new file mode 100644
index 0000000..e68045f
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/compose/ChronometerStateTest.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2024 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.chips.ui.compose
+
+import android.text.format.DateUtils.formatElapsedTime
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.cancelAndJoin
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ChronometerStateTest : SysuiTestCase() {
+
+    private lateinit var mockTimeSource: MutableTimeSource
+
+    @Before
+    fun setup() {
+        mockTimeSource = MutableTimeSource()
+    }
+
+    @Test
+    fun initialText_isCorrect() = runTest {
+        val state = ChronometerState(mockTimeSource, 0L)
+        assertThat(state.currentTimeText).isEqualTo(formatElapsedTime(0))
+    }
+
+    @Test
+    fun textUpdates_withTime() = runTest {
+        val startTime = 1000L
+        val state = ChronometerState(mockTimeSource, startTime)
+        val job = launch { state.run() }
+
+        val elapsedTime = 5000L
+        mockTimeSource.time = startTime + elapsedTime
+        advanceTimeBy(elapsedTime)
+        assertThat(state.currentTimeText).isEqualTo(formatElapsedTime(elapsedTime / 1000))
+
+        job.cancelAndJoin()
+    }
+
+    @Test
+    fun textUpdates_toLargerValue() = runTest {
+        val startTime = 1000L
+        val state = ChronometerState(mockTimeSource, startTime)
+        val job = launch { state.run() }
+
+        val elapsedTime = 15000L
+        mockTimeSource.time = startTime + elapsedTime
+        advanceTimeBy(elapsedTime)
+        assertThat(state.currentTimeText).isEqualTo(formatElapsedTime(elapsedTime / 1000))
+
+        job.cancelAndJoin()
+    }
+
+    @Test
+    fun textUpdates_afterResettingBase() = runTest {
+        val initialElapsedTime = 30000L
+        val startTime = 50000L
+        val state = ChronometerState(mockTimeSource, startTime)
+        val job = launch { state.run() }
+
+        mockTimeSource.time = startTime + initialElapsedTime
+        advanceTimeBy(initialElapsedTime)
+        assertThat(state.currentTimeText).isEqualTo(formatElapsedTime(initialElapsedTime / 1000))
+
+        job.cancelAndJoin()
+
+        val newElapsedTime = 5000L
+        val newStartTime = 100000L
+        val newState = ChronometerState(mockTimeSource, newStartTime)
+        val newJob = launch { newState.run() }
+
+        mockTimeSource.time = newStartTime + newElapsedTime
+        advanceTimeBy(newElapsedTime)
+        assertThat(newState.currentTimeText).isEqualTo(formatElapsedTime(newElapsedTime / 1000))
+
+        newJob.cancelAndJoin()
+    }
+}
+
+/** A fake implementation of [TimeSource] that allows the caller to set the current time */
+class MutableTimeSource(var time: Long = 0L) : TimeSource {
+    override fun getCurrentTime(): Long {
+        return time
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt
index 5fbdfbf..0c992e0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt
@@ -40,7 +40,7 @@
         allowTestableLooperAsMainThread()
         TestableLooper.get(this).runWithLooper {
             val chipView =
-                LayoutInflater.from(context).inflate(R.layout.ongoing_activity_chip, null)
+                LayoutInflater.from(context).inflate(R.layout.ongoing_activity_chip_primary, null)
             underTest = chipView.requireViewById(R.id.ongoing_activity_chip_background)
         }
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt
index 6f771175..9483f6d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt
@@ -48,7 +48,7 @@
         allowTestableLooperAsMainThread()
         TestableLooper.get(this).runWithLooper {
             val chipView =
-                LayoutInflater.from(mContext).inflate(R.layout.ongoing_activity_chip, null)
+                LayoutInflater.from(mContext).inflate(R.layout.ongoing_activity_chip_primary, null)
             textView = chipView.findViewById(R.id.ongoing_activity_chip_time)!!
             measureTextView()
             calculateDoesNotFixText()
@@ -161,7 +161,7 @@
     private fun measureTextView() {
         textView.measure(
             View.MeasureSpec.makeMeasureSpec(TEXT_VIEW_MAX_WIDTH, View.MeasureSpec.AT_MOST),
-            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
+            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
         )
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt
index 009b33b..3515c56 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/core/StatusBarInitializerTest.kt
@@ -26,10 +26,12 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.fragments.FragmentHostManager
 import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.plugins.fakeDarkIconDispatcher
 import com.android.systemui.statusbar.data.repository.fakeStatusBarModePerDisplayRepository
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment
 import com.android.systemui.statusbar.phone.fragment.dagger.HomeStatusBarComponent
 import com.android.systemui.statusbar.pipeline.shared.ui.composable.StatusBarRootFactory
+import com.android.systemui.statusbar.policy.statusBarConfigurationController
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
 import com.android.systemui.testKosmos
@@ -77,6 +79,8 @@
             componentFactory = mock(HomeStatusBarComponent.Factory::class.java),
             creationListeners = setOf(),
             statusBarModePerDisplayRepository = statusBarModePerDisplayRepository,
+            darkIconDispatcher = kosmos.fakeDarkIconDispatcher,
+            statusBarConfigurationController = kosmos.statusBarConfigurationController,
         )
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt
index 18eef33..884c35c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/LightBarControllerStoreImplTest.kt
@@ -51,7 +51,7 @@
     @Test
     fun forDisplay_startsInstance() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             verify(instance).start()
         }
@@ -59,7 +59,7 @@
     @Test
     fun beforeDisplayRemoved_doesNotStopInstances() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             verify(instance, never()).stop()
         }
@@ -67,7 +67,7 @@
     @Test
     fun displayRemoved_stopsInstance() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt
index a2c3c66..f37648a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayDarkIconDispatcherStoreTest.kt
@@ -56,7 +56,7 @@
     @Test
     fun beforeDisplayRemoved_doesNotStopInstances() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             verify(instance, never()).stop()
         }
@@ -64,7 +64,7 @@
     @Test
     fun displayRemoved_stopsInstance() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt
index 4a26fdf..e0a1f27 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarContentInsetsProviderStoreTest.kt
@@ -51,7 +51,7 @@
     @Test
     fun forDisplay_startsInstances() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             verify(instance).start()
         }
@@ -59,7 +59,7 @@
     @Test
     fun beforeDisplayRemoved_doesNotStopInstances() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             verify(instance, never()).stop()
         }
@@ -67,7 +67,7 @@
     @Test
     fun displayRemoved_stopsInstance() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt
index a9920ec5..11fd902 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/MultiDisplayStatusBarModeRepositoryStoreTest.kt
@@ -53,7 +53,7 @@
     @Test
     fun forDisplay_startsInstance() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             verify(instance).start()
         }
@@ -61,7 +61,7 @@
     @Test
     fun displayRemoved_stopsInstance() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt
index e65c04c..3cc592c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStoreImplTest.kt
@@ -56,7 +56,7 @@
     @Test
     fun beforeDisplayRemoved_doesNotStopInstances() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             verify(instance, never()).stop()
         }
@@ -64,7 +64,7 @@
     @Test
     fun displayRemoved_stopsInstance() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelTest.kt
new file mode 100644
index 0000000..8650e4b
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelTest.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 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.featurepods.media.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.shared.model.MediaData
+import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
+import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class MediaControlChipViewModelTest : SysuiTestCase() {
+    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+    private val underTest = kosmos.mediaControlChipViewModel
+
+    @Test
+    fun chip_noActiveMedia_IsHidden() =
+        kosmos.runTest {
+            val chip by collectLastValue(underTest.chip)
+
+            assertThat(chip).isInstanceOf(PopupChipModel.Hidden::class.java)
+        }
+
+    @Test
+    fun chip_activeMedia_IsShown() =
+        kosmos.runTest {
+            val chip by collectLastValue(underTest.chip)
+
+            val userMedia = MediaData(active = true, song = "test")
+            val instanceId = userMedia.instanceId
+
+            mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
+            mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+
+            assertThat(chip).isInstanceOf(PopupChipModel.Shown::class.java)
+        }
+
+    @Test
+    fun chip_songNameChanges_chipTextUpdated() =
+        kosmos.runTest {
+            val chip by collectLastValue(underTest.chip)
+
+            val initialSongName = "Initial Song"
+            val newSongName = "New Song"
+            val userMedia = MediaData(active = true, song = initialSongName)
+            val instanceId = userMedia.instanceId
+
+            mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
+            mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+
+            assertThat((chip as PopupChipModel.Shown).chipText).isEqualTo(initialSongName)
+
+            val updatedUserMedia = userMedia.copy(song = newSongName)
+            mediaFilterRepository.addSelectedUserMediaEntry(updatedUserMedia)
+
+            assertThat((chip as PopupChipModel.Shown).chipText).isEqualTo(newSongName)
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt
index 14787e1..fcbf0fe 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelTest.kt
@@ -22,7 +22,11 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.statusbar.chips.notification.shared.StatusBarPopupChips
+import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.shared.model.MediaData
+import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
+import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
+import com.android.systemui.statusbar.featurepods.popups.StatusBarPopupChips
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
@@ -35,12 +39,28 @@
 class StatusBarPopupChipsViewModelTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
+    private val mediaFilterRepository = kosmos.mediaFilterRepository
     private val underTest = kosmos.statusBarPopupChipsViewModel
 
     @Test
-    fun popupChips_allHidden_empty() =
+    fun shownPopupChips_allHidden_empty() =
         testScope.runTest {
-            val latest by collectLastValue(underTest.popupChips)
-            assertThat(latest).isEmpty()
+            val shownPopupChips by collectLastValue(underTest.shownPopupChips)
+            assertThat(shownPopupChips).isEmpty()
+        }
+
+    @Test
+    fun shownPopupChips_activeMedia_restHidden_mediaControlChipShown() =
+        testScope.runTest {
+            val shownPopupChips by collectLastValue(underTest.shownPopupChips)
+
+            val userMedia = MediaData(active = true, song = "test")
+            val instanceId = userMedia.instanceId
+
+            mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
+            mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+
+            assertThat(shownPopupChips).hasSize(1)
+            assertThat(shownPopupChips!!.first().chipId).isEqualTo(PopupChipId.MediaControl)
         }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinatorTest.kt
index d38fb50..5f154ac 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/OriginalUnseenKeyguardCoordinatorTest.kt
@@ -48,7 +48,7 @@
 import com.android.systemui.statusbar.notification.domain.interactor.lockScreenShowOnlyUnseenNotificationsSetting
 import com.android.systemui.statusbar.notification.domain.interactor.seenNotificationsInteractor
 import com.android.systemui.statusbar.notification.headsup.OnHeadsUpChangedListener
-import com.android.systemui.statusbar.notification.headsup.headsUpManager
+import com.android.systemui.statusbar.notification.headsup.mockHeadsUpManager
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.testKosmos
 import com.android.systemui.util.settings.FakeSettings
@@ -625,7 +625,7 @@
         val keyguardCoordinator =
             OriginalUnseenKeyguardCoordinator(
                 dumpManager = kosmos.dumpManager,
-                headsUpManager = kosmos.headsUpManager,
+                headsUpManager = kosmos.mockHeadsUpManager,
                 keyguardRepository = kosmos.keyguardRepository,
                 keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
                 logger = KeyguardCoordinatorLogger(logcatLogBuffer()),
@@ -663,7 +663,8 @@
 
         val onHeadsUpChangedListener: OnHeadsUpChangedListener
             get() =
-                argumentCaptor { verify(kosmos.headsUpManager).addListener(capture()) }.lastValue
+                argumentCaptor { verify(kosmos.mockHeadsUpManager).addListener(capture()) }
+                    .lastValue
     }
 
     companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
index be20bc1..d86c6ef 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt
@@ -225,7 +225,7 @@
             val displayId = 123
             darkIconRepository.darkState(displayId).value =
                 SysuiDarkIconDispatcher.DarkChange(emptyList(), 0f, 0xAABBCC)
-            val iconColors by collectLastValue(underTest.iconColors(displayId))
+            val iconColors by collectLastValue(underTest.iconColors(displayId)!!)
             assertThat(iconColors).isNotNull()
 
             assertThat(iconColors!!.tint).isEqualTo(0xAABBCC)
@@ -241,7 +241,7 @@
             val displayId = 321
             darkIconRepository.darkState(displayId).value =
                 SysuiDarkIconDispatcher.DarkChange(listOf(Rect(0, 0, 5, 5)), 0f, 0xAABBCC)
-            val iconColors by collectLastValue(underTest.iconColors(displayId))
+            val iconColors by collectLastValue(underTest.iconColors(displayId)!!)
             val staticDrawableColor = iconColors?.staticDrawableColor(Rect(6, 6, 7, 7))
             assertThat(staticDrawableColor).isEqualTo(DarkIconDispatcher.DEFAULT_ICON_TINT)
         }
@@ -252,7 +252,7 @@
             val displayId = 987
             darkIconRepository.darkState(displayId).value =
                 SysuiDarkIconDispatcher.DarkChange(listOf(Rect(0, 0, 5, 5)), 0f, 0xAABBCC)
-            val iconColors by collectLastValue(underTest.iconColors(displayId))
+            val iconColors by collectLastValue(underTest.iconColors(displayId)!!)
             assertThat(iconColors!!.staticDrawableColor(Rect(6, 6, 7, 7)))
                 .isEqualTo(DarkIconDispatcher.DEFAULT_ICON_TINT)
         }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
index 26c6eb5..9227119 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
@@ -35,6 +35,7 @@
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.promoted.AutomaticPromotionCoordinator.Companion.EXTRA_WAS_AUTOMATICALLY_PROMOTED
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style
 import com.android.systemui.testKosmos
@@ -110,6 +111,26 @@
 
     @Test
     @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun extractContent_wasPromotedAutomatically_false() {
+        val entry = createEntry { extras.putBoolean(EXTRA_WAS_AUTOMATICALLY_PROMOTED, false) }
+
+        val content = extractContent(entry)
+
+        assertThat(content!!.wasPromotedAutomatically).isFalse()
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun extractContent_wasPromotedAutomatically_true() {
+        val entry = createEntry { extras.putBoolean(EXTRA_WAS_AUTOMATICALLY_PROMOTED, true) }
+
+        val content = extractContent(entry)
+
+        assertThat(content!!.wasPromotedAutomatically).isTrue()
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
     @DisableFlags(android.app.Flags.FLAG_API_RICH_ONGOING)
     fun extractContent_apiFlagOff_shortCriticalTextNotExtracted() {
         val entry = createEntry { setShortCriticalText(TEST_SHORT_CRITICAL_TEXT) }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
index 1a1af2e..256da253 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
@@ -1,5 +1,6 @@
 package com.android.systemui.statusbar.notification.stack
 
+import android.platform.test.annotations.EnableFlags
 import android.service.notification.StatusBarNotification
 import android.testing.TestableLooper.RunWithLooper
 import android.view.LayoutInflater
@@ -20,6 +21,8 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.ExpandableView
+import com.android.systemui.statusbar.notification.shared.NotificationMinimalism
+import com.android.systemui.statusbar.notification.shelf.NotificationShelfIconContainer
 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.StackScrollAlgorithmState
 import com.android.systemui.util.mockito.mock
 import junit.framework.Assert.assertEquals
@@ -30,6 +33,7 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.mock
+import org.mockito.Mockito.spy
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
 
@@ -59,7 +63,7 @@
                 .inflate(
                     /* resource = */ R.layout.status_bar_notification_shelf,
                     /* root = */ root,
-                    /* attachToRoot = */ false
+                    /* attachToRoot = */ false,
                 ) as NotificationShelf
 
         whenever(ambientState.largeScreenShadeInterpolator).thenReturn(largeScreenShadeInterpolator)
@@ -128,6 +132,348 @@
     }
 
     @Test
+    @EnableFlags(NotificationMinimalism.FLAG_NAME)
+    fun testAlignment_splitShade_LTR() {
+        // Given: LTR mode, split shade
+        val width = 100
+        val actualWidth = 40
+        val iconContainerPadding = 16f
+        val shelfSpy =
+            prepareShelfSpy(
+                shelf,
+                rtl = false,
+                splitShade = true,
+                width = width,
+                actualWidth = actualWidth,
+                iconContainerPadding = iconContainerPadding,
+            )
+
+        // Then: shelf should align to end
+        assertTrue(shelfSpy.isAlignedToEnd)
+        assertTrue(shelfSpy.isAlignedToRight)
+        assertTrue(shelfSpy.mBackgroundNormal.alignToEnd)
+
+        // Then: icon container should align to end, right
+        val iconContainer = shelfSpy.shelfIcons as NotificationShelfIconContainer
+        assertTrue(iconContainer.alignToEnd)
+        assertTrue(iconContainer.isAlignedToRight)
+
+        // Then: icon container bounds are updated based on the widths and paddings
+        val actualPaddingStart = iconContainerPadding
+        val actualPaddingEnd = iconContainerPadding
+        val expectedLeftBound = width - actualWidth + actualPaddingStart
+        val expectedRightBound = width - actualPaddingEnd
+        assertEquals(expectedLeftBound, iconContainer.leftBound)
+        assertEquals(expectedRightBound, iconContainer.rightBound)
+    }
+
+    @Test
+    @EnableFlags(NotificationMinimalism.FLAG_NAME)
+    fun testAlignment_nonSplitShade_LTR() {
+        // Given: LTR mode, non split shade
+        val width = 100
+        val actualWidth = 40
+        val iconContainerPadding = 16f
+        val shelfSpy =
+            prepareShelfSpy(
+                shelf,
+                rtl = false,
+                splitShade = false,
+                width = width,
+                actualWidth = actualWidth,
+                iconContainerPadding = iconContainerPadding,
+            )
+
+        // Then: shelf should not align to end
+        // left bound of icon container should be 16f (actualPaddingStart)
+        // right bound of icon container should be 24f (actualWidth - actualPaddingEnd)
+        assertFalse(shelfSpy.isAlignedToEnd)
+        assertFalse(shelfSpy.isAlignedToRight)
+        assertFalse(shelfSpy.mBackgroundNormal.alignToEnd)
+
+        // Then: icon container should align to start, left
+
+        val iconContainer = shelfSpy.shelfIcons as NotificationShelfIconContainer
+        assertFalse(iconContainer.alignToEnd)
+        assertFalse(iconContainer.isAlignedToRight)
+
+        // Then: icon container bounds are updated based on the widths and paddings
+        val actualPaddingStart = iconContainerPadding
+        val actualPaddingEnd = iconContainerPadding
+        val expectedLeftBound = actualPaddingStart
+        val expectedRightBound = actualWidth - actualPaddingEnd
+        assertEquals(expectedLeftBound, iconContainer.leftBound)
+        assertEquals(expectedRightBound, iconContainer.rightBound)
+    }
+
+    @Test
+    @EnableFlags(NotificationMinimalism.FLAG_NAME)
+    fun testAlignment_splitShade_RTL() {
+        // Given: RTL mode, split shade
+        val width = 100
+        val actualWidth = 40
+        val iconContainerPadding = 16f
+        val shelfSpy =
+            prepareShelfSpy(
+                shelf,
+                rtl = true,
+                splitShade = true,
+                width = width,
+                actualWidth = actualWidth,
+                iconContainerPadding = iconContainerPadding,
+            )
+
+        // Then: shelf should align to end, but to left due to RTL
+        // left bound of icon container should be 16f (actualPaddingStart)
+        // right bound of icon container should be 24f (actualWidth - actualPaddingEnd)
+        assertTrue(shelfSpy.isAlignedToEnd)
+        assertFalse(shelfSpy.isAlignedToRight)
+        assertTrue(shelfSpy.mBackgroundNormal.alignToEnd)
+
+        // Then: icon container should align to end, left
+        val iconContainer = shelfSpy.shelfIcons as NotificationShelfIconContainer
+        assertTrue(iconContainer.alignToEnd)
+        assertFalse(iconContainer.isAlignedToRight)
+
+        // Then: icon container bounds are updated based on the widths and paddings
+        val actualPaddingStart = iconContainerPadding
+        val actualPaddingEnd = iconContainerPadding
+        val expectedLeftBound = actualPaddingStart
+        val expectedRightBound = actualWidth - actualPaddingEnd
+        assertEquals(expectedLeftBound, iconContainer.leftBound)
+        assertEquals(expectedRightBound, iconContainer.rightBound)
+    }
+
+    @Test
+    @EnableFlags(NotificationMinimalism.FLAG_NAME)
+    fun testAlignment_nonSplitShade_RTL() {
+        // Given: RTL mode, non split shade
+        val width = 100
+        val actualWidth = 40
+        val iconContainerPadding = 16f
+        val shelfSpy =
+            prepareShelfSpy(
+                shelf,
+                rtl = true,
+                splitShade = false,
+                width = width,
+                actualWidth = actualWidth,
+                iconContainerPadding = iconContainerPadding,
+            )
+
+        // Then: shelf should not align to end, but to right due to RTL
+        assertFalse(shelfSpy.isAlignedToEnd)
+        assertTrue(shelfSpy.isAlignedToRight)
+        assertFalse(shelfSpy.mBackgroundNormal.alignToEnd)
+
+        // Then: icon container should align to start, right
+        val iconContainer = shelfSpy.shelfIcons as NotificationShelfIconContainer
+        assertFalse(iconContainer.alignToEnd)
+        assertTrue(iconContainer.isAlignedToRight)
+
+        // Then: icon container bounds are updated based on the widths and paddings
+        val actualPaddingStart = iconContainerPadding
+        val actualPaddingEnd = iconContainerPadding
+        val expectedLeftBound = width - actualWidth + actualPaddingStart
+        val expectedRightBound = width - actualPaddingEnd
+        assertEquals(expectedLeftBound, iconContainer.leftBound)
+        assertEquals(expectedRightBound, iconContainer.rightBound)
+    }
+
+    @Test
+    @EnableFlags(NotificationMinimalism.FLAG_NAME)
+    fun testGetShelfLeftBound_splitShade_LTR() {
+        // Given: LTR mode, split shade
+        val width = 100
+        val actualWidth = 40
+        val shelfSpy =
+            prepareShelfSpy(
+                shelf,
+                rtl = false,
+                splitShade = true,
+                width = width,
+                actualWidth = actualWidth,
+            )
+
+        // When: get the left bound of the shelf
+        val shelfLeftBound = shelfSpy.shelfLeftBound
+
+        // Then: should be equal to shelf's width - actual width
+        val expectedLeftBound = (width - actualWidth).toFloat()
+        assertEquals(expectedLeftBound, shelfLeftBound)
+    }
+
+    @Test
+    @EnableFlags(NotificationMinimalism.FLAG_NAME)
+    fun testGetShelfRightBound_splitShade_LTR() {
+        // Given: LTR mode, split shade, width 100, actual width 40
+        val width = 100
+        val actualWidth = 40
+        val shelfSpy =
+            prepareShelfSpy(
+                shelf,
+                rtl = false,
+                splitShade = true,
+                width = width,
+                actualWidth = actualWidth,
+            )
+
+        // Then: the right bound of the shelf should be equal to shelf's width
+        val expectedRightBound = width.toFloat()
+        assertEquals(expectedRightBound, shelfSpy.shelfRightBound)
+    }
+
+    @Test
+    @EnableFlags(NotificationMinimalism.FLAG_NAME)
+    fun testGetShelfLeftBound_nonSplitShade_LTR() {
+        // Given: LTR mode, non split shade
+        val width = 100
+        val actualWidth = 40
+        val shelfSpy =
+            prepareShelfSpy(
+                shelf,
+                rtl = false,
+                splitShade = false,
+                width = width,
+                actualWidth = actualWidth,
+            )
+
+        // When: get the left bound of the shelf
+        val shelfLeftBound = shelfSpy.shelfLeftBound
+
+        // Then: should be equal to 0f
+        assertEquals(0f, shelfLeftBound)
+    }
+
+    @Test
+    @EnableFlags(NotificationMinimalism.FLAG_NAME)
+    fun testGetShelfRightBound_nonSplitShade_LTR() {
+        // Given: LTR mode, non split shade, width 100, actual width 40
+        val width = 100
+        val actualWidth = 40
+        val shelfSpy =
+            prepareShelfSpy(
+                shelf,
+                rtl = false,
+                splitShade = false,
+                width = width,
+                actualWidth = actualWidth,
+            )
+
+        // Then: the right bound of the shelf should be equal to shelf's actual width
+        assertEquals(actualWidth.toFloat(), shelfSpy.shelfRightBound)
+    }
+
+    @Test
+    @EnableFlags(NotificationMinimalism.FLAG_NAME)
+    fun testGetShelfLeftBound_splitShade_RTL() {
+        // Given: RTL mode, split shade
+        val width = 100
+        val actualWidth = 40
+        val shelfSpy =
+            prepareShelfSpy(
+                shelf,
+                rtl = true,
+                splitShade = true,
+                width = width,
+                actualWidth = actualWidth,
+            )
+
+        // When: get the left bound of the shelf
+        val shelfLeftBound = shelfSpy.shelfLeftBound
+
+        // Then: should be equal to 0f
+        assertEquals(0f, shelfLeftBound)
+    }
+
+    @Test
+    @EnableFlags(NotificationMinimalism.FLAG_NAME)
+    fun testGetShelfRightBound_splitShade_RTL() {
+        // Given: RTL mode, split shade, width 100, actual width 40
+        val width = 100
+        val actualWidth = 40
+        val shelfSpy =
+            prepareShelfSpy(
+                shelf,
+                rtl = true,
+                splitShade = true,
+                width = width,
+                actualWidth = actualWidth,
+            )
+
+        // Then: the right bound of the shelf should be equal to shelf's actual width
+        assertEquals(actualWidth.toFloat(), shelfSpy.shelfRightBound)
+    }
+
+    @Test
+    @EnableFlags(NotificationMinimalism.FLAG_NAME)
+    fun testGetShelfLeftBound_nonSplitShade_RTL() {
+        // Given: RTL mode, non split shade
+        val width = 100
+        val actualWidth = 40
+        val shelfSpy =
+            prepareShelfSpy(
+                shelf,
+                rtl = true,
+                splitShade = false,
+                width = width,
+                actualWidth = actualWidth,
+            )
+
+        // When: get the left bound of the shelf
+        val shelfLeftBound = shelfSpy.shelfLeftBound
+
+        // Then: should be equal to shelf's width - actual width
+        val expectedLeftBound = (width - actualWidth).toFloat()
+        assertEquals(expectedLeftBound, shelfLeftBound)
+    }
+
+    @Test
+    @EnableFlags(NotificationMinimalism.FLAG_NAME)
+    fun testGetShelfRightBound_nonSplitShade_RTL() {
+        // Given: LTR mode, non split shade, width 100, actual width 40
+        val width = 100
+        val actualWidth = 40
+        val shelfSpy =
+            prepareShelfSpy(
+                shelf,
+                rtl = true,
+                splitShade = false,
+                width = width,
+                actualWidth = actualWidth,
+            )
+
+        // Then: the right bound of the shelf should be equal to shelf's width
+        assertEquals(width.toFloat(), shelfSpy.shelfRightBound)
+    }
+
+    private fun prepareShelfSpy(
+        shelf: NotificationShelf,
+        rtl: Boolean,
+        splitShade: Boolean,
+        width: Int,
+        actualWidth: Int,
+        iconContainerPadding: Float? = null,
+    ): NotificationShelf {
+        val shelfSpy = spy(shelf)
+        whenever(shelfSpy.isLayoutRtl).thenReturn(rtl)
+        whenever(ambientState.useSplitShade).thenReturn(splitShade)
+        shelfSpy.layout(0, 0, width, 5)
+        shelfSpy.mShelfIcons.layout(0, 0, width, 5)
+        iconContainerPadding?.let {
+            shelfSpy.mShelfIcons.actualPaddingStart = it
+            shelfSpy.mShelfIcons.setActualPaddingEnd(it)
+        }
+        shelfSpy.setActualWidth(actualWidth.toFloat())
+
+        val iconContainerSpy = spy(shelf.mShelfIcons)
+        whenever(iconContainerSpy.isLayoutRtl).thenReturn(rtl)
+        whenever(shelfSpy.shelfIcons).thenReturn(iconContainerSpy)
+
+        return shelfSpy
+    }
+
+    @Test
     fun getAmountInShelf_lastViewBelowShelf_completelyInShelf() {
         val shelfClipStart = 0f
         val viewStart = 1f
@@ -152,7 +498,7 @@
                 /* scrollingFast= */ false,
                 /* expandingAnimated= */ false,
                 /* isLastChild= */ true,
-                shelfClipStart
+                shelfClipStart,
             )
         assertEquals(1f, amountInShelf)
     }
@@ -182,7 +528,7 @@
                 /* scrollingFast= */ false,
                 /* expandingAnimated= */ false,
                 /* isLastChild= */ true,
-                shelfClipStart
+                shelfClipStart,
             )
         assertEquals(1f, amountInShelf)
     }
@@ -212,7 +558,7 @@
                 /* scrollingFast= */ false,
                 /* expandingAnimated= */ false,
                 /* isLastChild= */ true,
-                shelfClipStart
+                shelfClipStart,
             )
         assertEquals(0.5f, amountInShelf)
     }
@@ -241,7 +587,7 @@
                 /* scrollingFast= */ false,
                 /* expandingAnimated= */ false,
                 /* isLastChild= */ true,
-                shelfClipStart
+                shelfClipStart,
             )
         assertEquals(0f, amountInShelf)
     }
@@ -250,7 +596,7 @@
     fun updateState_expansionChanging_shelfTransparent() {
         updateState_expansionChanging_shelfAlphaUpdated(
             expansionFraction = 0.25f,
-            expectedAlpha = 0.0f
+            expectedAlpha = 0.0f,
         )
     }
 
@@ -260,7 +606,7 @@
 
         updateState_expansionChanging_shelfAlphaUpdated(
             expansionFraction = 0.85f,
-            expectedAlpha = 0.0f
+            expectedAlpha = 0.0f,
         )
     }
 
@@ -281,7 +627,7 @@
 
         updateState_expansionChanging_shelfAlphaUpdated(
             expansionFraction = expansionFraction,
-            expectedAlpha = 0.123f
+            expectedAlpha = 0.123f,
         )
     }
 
@@ -330,7 +676,7 @@
                 /* scrollingFast= */ false,
                 /* expandingAnimated= */ false,
                 /* isLastChild= */ true,
-                shelfClipStart
+                shelfClipStart,
             )
         assertEquals(1f, amountInShelf)
     }
@@ -628,7 +974,7 @@
 
     private fun updateState_expansionChanging_shelfAlphaUpdated(
         expansionFraction: Float,
-        expectedAlpha: Float
+        expectedAlpha: Float,
     ) {
         val sbnMock: StatusBarNotification = mock()
         val mockEntry = mock<NotificationEntry>().apply { whenever(this.sbn).thenReturn(sbnMock) }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.kt
index f4c2545..216f51d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.kt
@@ -38,7 +38,7 @@
 import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor
 import com.android.systemui.statusbar.notification.domain.interactor.headsUpNotificationIconInteractor
 import com.android.systemui.statusbar.notification.headsup.PinnedStatus
-import com.android.systemui.statusbar.notification.headsup.headsUpManager
+import com.android.systemui.statusbar.notification.headsup.mockHeadsUpManager
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper
 import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation
@@ -75,7 +75,7 @@
     private val keyguardStateController = kosmos.keyguardStateController
     private val commandQueue = kosmos.commandQueue
     private val notificationRoundnessManager = mock<NotificationRoundnessManager>()
-    private var headsUpManager = kosmos.headsUpManager
+    private var headsUpManager = kosmos.mockHeadsUpManager
 
     private lateinit var testHelper: NotificationTestHelper
     private lateinit var row: ExpandableNotificationRow
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt
index 90506a1..d163726 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt
@@ -56,7 +56,7 @@
     @Test
     fun beforeDisplayRemoved_doesNotStopInstances() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             verify(instance, never()).stop()
         }
@@ -64,7 +64,7 @@
     @Test
     fun displayRemoved_stopsInstance() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt
index 2d9880a..659d91a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt
@@ -39,7 +39,7 @@
     fun isLowProfile_lightsOutStatusBarMode_false() = runTest {
         statusBarModeRepository.defaultDisplay.statusBarMode.value = StatusBarMode.LIGHTS_OUT
 
-        val actual by collectLastValue(interactor.isLowProfile(DISPLAY_ID))
+        val actual by collectLastValue(interactor.isLowProfile(DISPLAY_ID)!!)
 
         assertThat(actual).isTrue()
     }
@@ -49,7 +49,7 @@
         statusBarModeRepository.defaultDisplay.statusBarMode.value =
             StatusBarMode.LIGHTS_OUT_TRANSPARENT
 
-        val actual by collectLastValue(interactor.isLowProfile(DISPLAY_ID))
+        val actual by collectLastValue(interactor.isLowProfile(DISPLAY_ID)!!)
 
         assertThat(actual).isTrue()
     }
@@ -58,7 +58,7 @@
     fun isLowProfile_transparentStatusBarMode_false() = runTest {
         statusBarModeRepository.defaultDisplay.statusBarMode.value = StatusBarMode.TRANSPARENT
 
-        val actual by collectLastValue(interactor.isLowProfile(DISPLAY_ID))
+        val actual by collectLastValue(interactor.isLowProfile(DISPLAY_ID)!!)
 
         assertThat(actual).isFalse()
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt
index f76ee5e..cd3539d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaListenerTest.kt
@@ -114,7 +114,8 @@
     fun setUp() {
         allowTestableLooperAsMainThread()
         TestableLooper.get(this).runWithLooper {
-            chipView = LayoutInflater.from(mContext).inflate(R.layout.ongoing_activity_chip, null)
+            chipView =
+                LayoutInflater.from(mContext).inflate(R.layout.ongoing_activity_chip_primary, null)
         }
 
         MockitoAnnotations.initMocks(this)
@@ -498,7 +499,7 @@
         lateinit var newChipView: View
         TestableLooper.get(this).runWithLooper {
             newChipView =
-                LayoutInflater.from(mContext).inflate(R.layout.ongoing_activity_chip, null)
+                LayoutInflater.from(mContext).inflate(R.layout.ongoing_activity_chip_primary, null)
         }
 
         // Change the chip view associated with the controller.
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
index 647b5f8..cf512cd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerViaRepoTest.kt
@@ -29,7 +29,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags.FLAG_STATUS_BAR_CALL_CHIP_NOTIFICATION_ICON
-import com.android.systemui.Flags.FLAG_STATUS_BAR_CHIPS_MODERNIZATION
 import com.android.systemui.Flags.FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS
 import com.android.systemui.Flags.FLAG_STATUS_BAR_USE_REPOS_FOR_CALL_CHIP
 import com.android.systemui.SysuiTestCase
@@ -104,7 +103,8 @@
     fun setUp() {
         allowTestableLooperAsMainThread()
         TestableLooper.get(this).runWithLooper {
-            chipView = LayoutInflater.from(mContext).inflate(R.layout.ongoing_activity_chip, null)
+            chipView =
+                LayoutInflater.from(mContext).inflate(R.layout.ongoing_activity_chip_primary, null)
         }
 
         whenever(mockStatusBarWindowControllerStore.defaultDisplay)
@@ -134,12 +134,7 @@
         testScope.runCurrent()
         reset(mockOngoingCallListener)
 
-        whenever(
-                mockIActivityManager.getUidProcessState(
-                    eq(CALL_UID),
-                    any(),
-                )
-            )
+        whenever(mockIActivityManager.getUidProcessState(eq(CALL_UID), any()))
             .thenReturn(PROC_STATE_INVISIBLE)
     }
 
@@ -225,38 +220,18 @@
 
     @Test
     fun notifRepoHasOngoingCallNotifThenScreeningNotif_listenerNotifiedTwice() {
-        setNotifOnRepo(
-            activeNotificationModel(
-                key = "notif",
-                callType = CallType.Ongoing,
-            )
-        )
+        setNotifOnRepo(activeNotificationModel(key = "notif", callType = CallType.Ongoing))
 
-        setNotifOnRepo(
-            activeNotificationModel(
-                key = "notif",
-                callType = CallType.Screening,
-            )
-        )
+        setNotifOnRepo(activeNotificationModel(key = "notif", callType = CallType.Screening))
 
         verify(mockOngoingCallListener, times(2)).onOngoingCallStateChanged(any())
     }
 
     @Test
     fun notifRepoHasOngoingCallNotifThenScreeningNotif_repoUpdated() {
-        setNotifOnRepo(
-            activeNotificationModel(
-                key = "notif",
-                callType = CallType.Ongoing,
-            )
-        )
+        setNotifOnRepo(activeNotificationModel(key = "notif", callType = CallType.Ongoing))
 
-        setNotifOnRepo(
-            activeNotificationModel(
-                key = "notif",
-                callType = CallType.Screening,
-            )
-        )
+        setNotifOnRepo(activeNotificationModel(key = "notif", callType = CallType.Screening))
 
         assertThat(ongoingCallRepository.ongoingCallState.value)
             .isInstanceOf(OngoingCallModel.NoCall::class.java)
@@ -289,7 +264,7 @@
 
         chipView.measure(
             View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
-            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
+            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
         )
 
         assertThat(chipView.findViewById<View>(R.id.ongoing_activity_chip_time)?.measuredWidth)
@@ -309,7 +284,7 @@
 
         chipView.measure(
             View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
-            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
+            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
         )
 
         assertThat(chipView.findViewById<View>(R.id.ongoing_activity_chip_time)?.measuredWidth)
@@ -323,11 +298,7 @@
             // Re-create the notification each time so that it's considered a different object and
             // will re-trigger the whole flow.
             setNotifOnRepo(
-                activeNotificationModel(
-                    key = "notif$i",
-                    callType = CallType.Ongoing,
-                    whenTime = 44,
-                )
+                activeNotificationModel(key = "notif$i", callType = CallType.Ongoing, whenTime = 44)
             )
         }
 
@@ -337,12 +308,7 @@
     /** Regression test for b/216248574. */
     @Test
     fun repoHasCallNotif_getUidProcessStateThrowsException_noCrash() {
-        whenever(
-                mockIActivityManager.getUidProcessState(
-                    eq(CALL_UID),
-                    any(),
-                )
-            )
+        whenever(mockIActivityManager.getUidProcessState(eq(CALL_UID), any()))
             .thenThrow(SecurityException())
 
         // No assert required, just check no crash
@@ -352,14 +318,7 @@
     /** Regression test for b/216248574. */
     @Test
     fun repoHasCallNotif_registerUidObserverThrowsException_noCrash() {
-        whenever(
-                mockIActivityManager.registerUidObserver(
-                    any(),
-                    any(),
-                    any(),
-                    any(),
-                )
-            )
+        whenever(mockIActivityManager.registerUidObserver(any(), any(), any(), any()))
             .thenThrow(SecurityException())
 
         // No assert required, just check no crash
@@ -416,11 +375,7 @@
     @Test
     fun hasOngoingCall_repoHasUnrelatedNotif_returnsFalse() {
         setNotifOnRepo(
-            activeNotificationModel(
-                key = "unrelated",
-                callType = CallType.None,
-                uid = CALL_UID,
-            )
+            activeNotificationModel(key = "unrelated", callType = CallType.None, uid = CALL_UID)
         )
 
         assertThat(controller.hasOngoingCall()).isFalse()
@@ -441,20 +396,11 @@
 
     @Test
     fun hasOngoingCall_repoHasCallNotifAndCallAppNotVisible_returnsTrue() {
-        whenever(
-                mockIActivityManager.getUidProcessState(
-                    eq(CALL_UID),
-                    any(),
-                )
-            )
+        whenever(mockIActivityManager.getUidProcessState(eq(CALL_UID), any()))
             .thenReturn(PROC_STATE_INVISIBLE)
 
         setNotifOnRepo(
-            activeNotificationModel(
-                key = "notif",
-                callType = CallType.Ongoing,
-                uid = CALL_UID,
-            )
+            activeNotificationModel(key = "notif", callType = CallType.Ongoing, uid = CALL_UID)
         )
 
         assertThat(controller.hasOngoingCall()).isTrue()
@@ -466,11 +412,7 @@
             .thenReturn(PROC_STATE_VISIBLE)
 
         setNotifOnRepo(
-            activeNotificationModel(
-                key = "notif",
-                callType = CallType.Ongoing,
-                uid = CALL_UID,
-            )
+            activeNotificationModel(key = "notif", callType = CallType.Ongoing, uid = CALL_UID)
         )
 
         assertThat(controller.hasOngoingCall()).isFalse()
@@ -482,11 +424,7 @@
         controller.setChipView(invalidChipView)
 
         setNotifOnRepo(
-            activeNotificationModel(
-                key = "notif",
-                callType = CallType.Ongoing,
-                uid = CALL_UID,
-            )
+            activeNotificationModel(key = "notif", callType = CallType.Ongoing, uid = CALL_UID)
         )
 
         assertThat(controller.hasOngoingCall()).isFalse()
@@ -532,7 +470,7 @@
         lateinit var newChipView: View
         TestableLooper.get(this).runWithLooper {
             newChipView =
-                LayoutInflater.from(mContext).inflate(R.layout.ongoing_activity_chip, null)
+                LayoutInflater.from(mContext).inflate(R.layout.ongoing_activity_chip_primary, null)
         }
 
         // Change the chip view associated with the controller.
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
index 0aaf89a..a9db0b7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle
+import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -41,6 +42,8 @@
 
     override val ongoingActivityChips = MutableStateFlow(MultipleOngoingActivityChipsModel())
 
+    override val statusBarPopupChips = MutableStateFlow(emptyList<PopupChipModel.Shown>())
+
     override val isHomeStatusBarAllowedByScene = MutableStateFlow(false)
 
     override val shouldShowOperatorNameView = MutableStateFlow(false)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt
index 7a9d017..769f012 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/window/MultiDisplayStatusBarWindowControllerStoreTest.kt
@@ -53,7 +53,7 @@
     @Test
     fun beforeDisplayRemoved_doesNotStopInstances() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             verify(instance, never()).stop()
         }
@@ -61,7 +61,7 @@
     @Test
     fun displayRemoved_stopsInstance() =
         testScope.runTest {
-            val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+            val instance = underTest.forDisplay(DEFAULT_DISPLAY)!!
 
             fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGesture.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGesture.kt
new file mode 100644
index 0000000..68b5772
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGesture.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2024 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.touchpad.tutorial.ui.gesture
+
+import android.graphics.PointF
+import android.view.MotionEvent
+import kotlin.math.cos
+import kotlin.math.sin
+
+/** Test helper to generate circular gestures or full EasterEgg gesture */
+object EasterEggGesture {
+
+    fun motionEventsForGesture(): List<MotionEvent> {
+        val gesturePath = generateCircularGesturePoints(circlesCount = 3)
+        val events =
+            TwoFingerGesture.eventsForFullGesture { gesturePath.forEach { p -> move(p.x, p.y) } }
+        return events
+    }
+
+    /**
+     * Generates list of points that would make up clockwise circular motion with given [radius].
+     * [circlesCount] determines how many full circles gesture should perform. [radiusNoiseFraction]
+     * can introduce noise to mimic real-world gesture which is not perfect - shape will be still
+     * circular but radius at any given point can be deviate from given radius by
+     * [radiusNoiseFraction].
+     */
+    fun generateCircularGesturePoints(
+        circlesCount: Int,
+        radiusNoiseFraction: Double? = null,
+        radius: Float = 100f,
+    ): List<PointF> {
+        val pointsPerCircle = 50
+        val angleStep = 360 / pointsPerCircle
+        val angleBuffer = 20 // buffer to make sure we're doing a bit more than 360 degree
+        val totalAngle = circlesCount * (360 + angleBuffer)
+        // Because all gestures in tests should start at (DEFAULT_X, DEFAULT_Y) we need to shift
+        // circle center x coordinate by radius
+        val centerX = -radius
+        val centerY = 0f
+
+        val randomNoise: (Double) -> Double =
+            if (radiusNoiseFraction == null) {
+                { 0.0 }
+            } else {
+                { radianAngle -> sin(radianAngle * 2) * radiusNoiseFraction }
+            }
+
+        val events = mutableListOf<PointF>()
+        var currentAngle = 0f
+        // as cos(0) == 1 and sin(0) == 0 we start gesture at position of (radius, 0) and go
+        // clockwise - first Y increases and X decreases
+        while (currentAngle < totalAngle) {
+            val radianAngle = Math.toRadians(currentAngle.toDouble())
+            val radiusWithNoise = radius * (1 + randomNoise(radianAngle).toFloat())
+            val x = centerX + radiusWithNoise * cos(radianAngle).toFloat()
+            val y = centerY + radiusWithNoise * sin(radianAngle).toFloat()
+            events.add(PointF(x, y))
+            currentAngle += angleStep
+        }
+        return events
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureRecognizerTest.kt
new file mode 100644
index 0000000..3829778
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureRecognizerTest.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2024 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.touchpad.tutorial.ui.gesture
+
+import android.graphics.PointF
+import android.view.MotionEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.touchpad.tutorial.ui.gesture.EasterEggGesture.generateCircularGesturePoints
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class EasterEggGestureRecognizerTest : SysuiTestCase() {
+
+    private var triggered = false
+    private val gestureRecognizer = EasterEggGestureRecognizer()
+
+    @Before
+    fun setup() {
+        gestureRecognizer.addGestureStateCallback { triggered = it == GestureState.Finished }
+    }
+
+    @Test
+    fun easterEggTriggeredAfterThreeCircles() {
+        assertStateAfterTwoFingerGesture(
+            gesturePath = generateCircularGesturePoints(circlesCount = 3),
+            wasTriggered = true,
+        )
+    }
+
+    @Test
+    fun easterEggTriggeredAfterThreeImperfectCircles() {
+        assertStateAfterTwoFingerGesture(
+            gesturePath =
+                generateCircularGesturePoints(circlesCount = 3, radiusNoiseFraction = 0.2),
+            wasTriggered = true,
+        )
+    }
+
+    @Test
+    fun easterEggTriggeredAfterFiveCircles() {
+        assertStateAfterTwoFingerGesture(
+            gesturePath = generateCircularGesturePoints(circlesCount = 5),
+            wasTriggered = true,
+        )
+    }
+
+    @Test
+    fun easterEggNotTriggeredAfterTwoCircles() {
+        assertStateAfterTwoFingerGesture(
+            gesturePath = generateCircularGesturePoints(circlesCount = 2),
+            wasTriggered = false,
+        )
+    }
+
+    @Test
+    fun easterEggNotTriggeredAfterVariousSwipes() {
+        val allSwipeGestures =
+            listOf(
+                // two finger gestures
+                TwoFingerGesture.swipeUp(),
+                TwoFingerGesture.swipeDown(),
+                TwoFingerGesture.swipeLeft(),
+                TwoFingerGesture.swipeRight(),
+                // three finger gestures
+                ThreeFingerGesture.swipeUp(),
+                ThreeFingerGesture.swipeDown(),
+                ThreeFingerGesture.swipeLeft(),
+                ThreeFingerGesture.swipeRight(),
+                // four finger gestures
+                FourFingerGesture.swipeUp(),
+                FourFingerGesture.swipeDown(),
+                FourFingerGesture.swipeLeft(),
+                FourFingerGesture.swipeRight(),
+            )
+        allSwipeGestures.forEach { gesture ->
+            assertStateAfterEvents(events = gesture, wasTriggered = false)
+        }
+    }
+
+    private fun assertStateAfterEvents(events: List<MotionEvent>, wasTriggered: Boolean) {
+        events.forEach { gestureRecognizer.accept(it) }
+        assertThat(triggered).isEqualTo(wasTriggered)
+    }
+
+    private fun assertStateAfterTwoFingerGesture(gesturePath: List<PointF>, wasTriggered: Boolean) {
+        val events =
+            TwoFingerGesture.eventsForFullGesture { gesturePath.forEach { p -> move(p.x, p.y) } }
+        assertStateAfterEvents(events = events, wasTriggered = wasTriggered)
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureTest.kt
deleted file mode 100644
index ff0cec5..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureTest.kt
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2024 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.touchpad.tutorial.ui.gesture
-
-import android.view.MotionEvent
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.touchpad.tutorial.ui.gesture.MultiFingerGesture.Companion.SWIPE_DISTANCE
-import com.google.common.truth.Truth.assertThat
-import kotlin.math.cos
-import kotlin.math.sin
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class EasterEggGestureTest : SysuiTestCase() {
-
-    private data class Point(val x: Float, val y: Float)
-
-    private var triggered = false
-    private val handler =
-        TouchpadGestureHandler(
-            BackGestureRecognizer(gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt()),
-            EasterEggGestureMonitor(callback = { triggered = true }),
-        )
-
-    @Test
-    fun easterEggTriggeredAfterThreeCircles() {
-        assertStateAfterTwoFingerGesture(
-            gesturePath = generateCircularGesturePoints(circlesCount = 3),
-            wasTriggered = true,
-        )
-    }
-
-    @Test
-    fun easterEggTriggeredAfterThreeImperfectCircles() {
-        assertStateAfterTwoFingerGesture(
-            gesturePath =
-                generateCircularGesturePoints(circlesCount = 3, radiusNoiseFraction = 0.2),
-            wasTriggered = true,
-        )
-    }
-
-    @Test
-    fun easterEggTriggeredAfterFiveCircles() {
-        assertStateAfterTwoFingerGesture(
-            gesturePath = generateCircularGesturePoints(circlesCount = 5),
-            wasTriggered = true,
-        )
-    }
-
-    @Test
-    fun easterEggNotTriggeredAfterTwoCircles() {
-        assertStateAfterTwoFingerGesture(
-            gesturePath = generateCircularGesturePoints(circlesCount = 2),
-            wasTriggered = false,
-        )
-    }
-
-    @Test
-    fun easterEggNotTriggeredAfterVariousSwipes() {
-        val allSwipeGestures =
-            listOf(
-                // two finger gestures
-                TwoFingerGesture.swipeUp(),
-                TwoFingerGesture.swipeDown(),
-                TwoFingerGesture.swipeLeft(),
-                TwoFingerGesture.swipeRight(),
-                // three finger gestures
-                ThreeFingerGesture.swipeUp(),
-                ThreeFingerGesture.swipeDown(),
-                ThreeFingerGesture.swipeLeft(),
-                ThreeFingerGesture.swipeRight(),
-                // four finger gestures
-                FourFingerGesture.swipeUp(),
-                FourFingerGesture.swipeDown(),
-                FourFingerGesture.swipeLeft(),
-                FourFingerGesture.swipeRight(),
-            )
-        allSwipeGestures.forEach { gesture ->
-            assertStateAfterEvents(events = gesture, wasTriggered = false)
-        }
-    }
-
-    private fun assertStateAfterEvents(events: List<MotionEvent>, wasTriggered: Boolean) {
-        events.forEach { handler.onMotionEvent(it) }
-        assertThat(triggered).isEqualTo(wasTriggered)
-    }
-
-    private fun assertStateAfterTwoFingerGesture(gesturePath: List<Point>, wasTriggered: Boolean) {
-        val events =
-            TwoFingerGesture.eventsForFullGesture { gesturePath.forEach { (x, y) -> move(x, y) } }
-        assertStateAfterEvents(events = events, wasTriggered = wasTriggered)
-    }
-
-    /**
-     * Generates list of points that would make up clockwise circular motion with given [radius].
-     * [circlesCount] determines how many full circles gesture should perform. [radiusNoiseFraction]
-     * can introduce noise to mimic real-world gesture which is not perfect - shape will be still
-     * circular but radius at any given point can be deviate from given radius by
-     * [radiusNoiseFraction].
-     */
-    private fun generateCircularGesturePoints(
-        circlesCount: Int,
-        radiusNoiseFraction: Double? = null,
-        radius: Float = 100f,
-    ): List<Point> {
-        val pointsPerCircle = 50
-        val angleStep = 360 / pointsPerCircle
-        val angleBuffer = 20 // buffer to make sure we're doing a bit more than 360 degree
-        val totalAngle = circlesCount * (360 + angleBuffer)
-        // Because all gestures in tests should start at (DEFAULT_X, DEFAULT_Y) we need to shift
-        // circle center x coordinate by radius
-        val centerX = -radius
-        val centerY = 0f
-
-        val events = mutableListOf<Point>()
-        val randomNoise: (Double) -> Double =
-            if (radiusNoiseFraction == null) {
-                { 0.0 }
-            } else {
-                { radianAngle -> sin(radianAngle * 2) * radiusNoiseFraction }
-            }
-
-        var currentAngle = 0f
-        // as cos(0) == 1 and sin(0) == 0 we start gesture at position of (radius, 0) and go
-        // clockwise - first Y increases and X decreases
-        while (currentAngle < totalAngle) {
-            val radianAngle = Math.toRadians(currentAngle.toDouble())
-            val radiusWithNoise = radius * (1 + randomNoise(radianAngle).toFloat())
-            val x = centerX + radiusWithNoise * cos(radianAngle).toFloat()
-            val y = centerY + radiusWithNoise * sin(radianAngle).toFloat()
-            events.add(Point(x, y))
-            currentAngle += angleStep
-        }
-        return events
-    }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureRecognizerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureRecognizerTest.kt
index 8972f3e..8b526bb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureRecognizerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/ThreeFingerGestureRecognizerTest.kt
@@ -30,12 +30,14 @@
 import com.android.systemui.touchpad.ui.gesture.FakeVelocityTracker
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
 @SmallTest
+@Ignore("b/386412866")
 @RunWith(ParameterizedAndroidJunit4::class)
 class ThreeFingerGestureRecognizerTest(
     private val recognizer: GestureRecognizer,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadEventsFilterTest.kt
similarity index 75%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadEventsFilterTest.kt
index c302b40..20bcb3e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadEventsFilterTest.kt
@@ -33,12 +33,11 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-class TouchpadGestureHandlerTest : SysuiTestCase() {
+class TouchpadEventsFilterTest : SysuiTestCase() {
 
     private var gestureState: GestureState = GestureState.NotStarted
     private val gestureRecognizer =
         BackGestureRecognizer(gestureDistanceThresholdPx = SWIPE_DISTANCE.toInt())
-    private val handler = TouchpadGestureHandler(gestureRecognizer, EasterEggGestureMonitor {})
 
     @Before
     fun before() {
@@ -48,21 +47,21 @@
     @Test
     fun handlesEventsFromTouchpad() {
         val event = downEvent(source = SOURCE_MOUSE, toolType = TOOL_TYPE_FINGER)
-        val eventHandled = handler.onMotionEvent(event)
+        val eventHandled = gestureRecognizer.handleTouchpadMotionEvent(event)
         assertThat(eventHandled).isTrue()
     }
 
     @Test
     fun ignoresEventsFromMouse() {
         val event = downEvent(source = SOURCE_MOUSE, toolType = TOOL_TYPE_MOUSE)
-        val eventHandled = handler.onMotionEvent(event)
+        val eventHandled = gestureRecognizer.handleTouchpadMotionEvent(event)
         assertThat(eventHandled).isFalse()
     }
 
     @Test
     fun ignoresEventsFromTouch() {
         val event = downEvent(source = SOURCE_TOUCHSCREEN, toolType = TOOL_TYPE_FINGER)
-        val eventHandled = handler.onMotionEvent(event)
+        val eventHandled = gestureRecognizer.handleTouchpadMotionEvent(event)
         assertThat(eventHandled).isFalse()
     }
 
@@ -70,25 +69,10 @@
     fun ignoresButtonClicksFromTouchpad() {
         val event = downEvent(source = SOURCE_MOUSE, toolType = TOOL_TYPE_FINGER)
         event.buttonState = MotionEvent.BUTTON_PRIMARY
-        val eventHandled = handler.onMotionEvent(event)
+        val eventHandled = gestureRecognizer.handleTouchpadMotionEvent(event)
         assertThat(eventHandled).isFalse()
     }
 
     private fun downEvent(source: Int, toolType: Int) =
         motionEvent(action = ACTION_DOWN, x = 0f, y = 0f, source = source, toolType = toolType)
-
-    @Test
-    fun triggersGestureDoneForThreeFingerGesture() {
-        backGestureEvents().forEach { handler.onMotionEvent(it) }
-
-        assertThat(gestureState).isEqualTo(GestureState.Finished)
-    }
-
-    private fun backGestureEvents(): List<MotionEvent> {
-        return ThreeFingerGesture.eventsForFullGesture {
-            move(deltaX = SWIPE_DISTANCE / 4)
-            move(deltaX = SWIPE_DISTANCE / 2)
-            move(deltaX = SWIPE_DISTANCE)
-        }
-    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModelTest.kt
index f90e14c..79c1f9f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModelTest.kt
@@ -54,13 +54,6 @@
     }
 
     @Test
-    fun easterEggNotTriggeredAtStart() =
-        kosmos.runTest {
-            val easterEggTriggered by collectLastValue(viewModel.easterEggTriggered)
-            assertThat(easterEggTriggered).isFalse()
-        }
-
-    @Test
     fun emitsProgressStateWithLeftProgressAnimation() =
         kosmos.runTest {
             assertProgressWhileMovingFingers(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/EasterEggGestureViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/EasterEggGestureViewModelTest.kt
new file mode 100644
index 0000000..4af3742
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/EasterEggGestureViewModelTest.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024 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.touchpad.tutorial.ui.viewmodel
+
+import android.view.MotionEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.testKosmos
+import com.android.systemui.touchpad.tutorial.ui.gesture.EasterEggGesture
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class EasterEggGestureViewModelTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val viewModel = EasterEggGestureViewModel()
+
+    @Before
+    fun before() {
+        kosmos.useUnconfinedTestDispatcher()
+    }
+
+    @Test
+    fun easterEggNotTriggeredAtStart() =
+        kosmos.runTest {
+            val easterEggTriggered by collectLastValue(viewModel.easterEggTriggered)
+            assertThat(easterEggTriggered).isFalse()
+        }
+
+    @Test
+    fun emitsTrueOnEasterEggTriggered() =
+        kosmos.runTest {
+            assertStateAfterEvents(
+                events = EasterEggGesture.motionEventsForGesture(),
+                expected = true,
+            )
+        }
+
+    @Test
+    fun emitsFalseOnEasterEggCallbackExecuted() =
+        kosmos.runTest {
+            val easterEggTriggered by collectLastValue(viewModel.easterEggTriggered)
+            EasterEggGesture.motionEventsForGesture().forEach { viewModel.accept(it) }
+
+            assertThat(easterEggTriggered).isEqualTo(true)
+            viewModel.onEasterEggFinished()
+            assertThat(easterEggTriggered).isEqualTo(false)
+        }
+
+    private fun Kosmos.assertStateAfterEvents(events: List<MotionEvent>, expected: Boolean) {
+        val state by collectLastValue(viewModel.easterEggTriggered)
+        events.forEach { viewModel.accept(it) }
+        assertThat(state).isEqualTo(expected)
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModelTest.kt
index 3c06352..4dfd01a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModelTest.kt
@@ -70,13 +70,6 @@
     }
 
     @Test
-    fun easterEggNotTriggeredAtStart() =
-        kosmos.runTest {
-            val easterEggTriggered by collectLastValue(viewModel.easterEggTriggered)
-            assertThat(easterEggTriggered).isFalse()
-        }
-
-    @Test
     fun emitsProgressStateWithAnimationMarkers() =
         kosmos.runTest {
             assertStateAfterEvents(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModelTest.kt
index a2d8a8b..66bf778 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModelTest.kt
@@ -74,13 +74,6 @@
     }
 
     @Test
-    fun easterEggNotTriggeredAtStart() =
-        kosmos.runTest {
-            val easterEggTriggered by collectLastValue(viewModel.easterEggTriggered)
-            assertThat(easterEggTriggered).isFalse()
-        }
-
-    @Test
     fun emitsProgressStateWithAnimationMarkers() =
         kosmos.runTest {
             assertStateAfterEvents(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractorTest.kt
new file mode 100644
index 0000000..bc16bec
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractorTest.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 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.window.domain.interactor
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@ExperimentalCoroutinesApi
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class WindowRootViewBlurInteractorTest : SysuiTestCase() {
+    val kosmos = testKosmos()
+    val testScope = kosmos.testScope
+
+    val underTest by lazy { kosmos.windowRootViewBlurInteractor }
+
+    @Test
+    fun bouncerBlurIsAppliedImmediately() =
+        testScope.runTest {
+            val blurRadius by collectLastValue(underTest.blurRadius)
+            val isBlurOpaque by collectLastValue(underTest.isBlurOpaque)
+
+            underTest.requestBlurForBouncer(10)
+
+            assertThat(blurRadius).isEqualTo(10)
+            assertThat(isBlurOpaque).isFalse()
+        }
+
+    @Test
+    fun shadeBlurIsNotAppliedWhenBouncerBlurIsActive() =
+        testScope.runTest {
+            kosmos.fakeKeyguardBouncerRepository.setPrimaryShow(true)
+
+            assertThat(underTest.requestBlurForShade(30, true)).isFalse()
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt
new file mode 100644
index 0000000..b97fe57
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelTest.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 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.window.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.lifecycle.activateIn
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@ExperimentalCoroutinesApi
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class WindowRootViewModelTest : SysuiTestCase() {
+    val kosmos = testKosmos()
+    val testScope = kosmos.testScope
+
+    val underTest by lazy { kosmos.windowRootViewModel }
+
+    @Before
+    fun setup() {
+        underTest.activateIn(testScope)
+    }
+
+    @Test
+    fun bouncerTransitionChangesWindowBlurRadius() =
+        testScope.runTest {
+            val blurState by collectLastValue(underTest.blurState)
+            runCurrent()
+
+            kosmos.fakeBouncerTransitions.first().windowBlurRadius.value = 30.0f
+            runCurrent()
+
+            assertThat(blurState).isEqualTo(BlurState(radius = 30, isOpaque = false))
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/TestableBubbleController.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/TestableBubbleController.java
index 4a5ebd0..aa71b84 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/TestableBubbleController.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/wmshell/TestableBubbleController.java
@@ -25,7 +25,6 @@
 
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.bubbles.BubbleController;
 import com.android.wm.shell.bubbles.BubbleData;
 import com.android.wm.shell.bubbles.BubbleDataRepository;
@@ -33,6 +32,8 @@
 import com.android.wm.shell.bubbles.BubblePositioner;
 import com.android.wm.shell.bubbles.properties.BubbleProperties;
 import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.DisplayInsetsController;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
@@ -62,7 +63,8 @@
             BubbleDataRepository dataRepository,
             IStatusBarService statusBarService,
             WindowManager windowManager,
-            WindowManagerShellWrapper windowManagerShellWrapper,
+            DisplayInsetsController displayInsetsController,
+            DisplayImeController displayImeController,
             UserManager userManager,
             LauncherApps launcherApps,
             BubbleLogger bubbleLogger,
@@ -81,8 +83,8 @@
             BubbleProperties bubbleProperties) {
         super(context, shellInit, shellCommandHandler, shellController, data, Runnable::run,
                 floatingContentCoordinator, dataRepository, statusBarService, windowManager,
-                windowManagerShellWrapper, userManager, launcherApps, bubbleLogger,
-                taskStackListener, shellTaskOrganizer, positioner, displayController,
+                displayInsetsController, displayImeController, userManager, launcherApps,
+                bubbleLogger, taskStackListener, shellTaskOrganizer, positioner, displayController,
                 oneHandedOptional, dragAndDropController, shellMainExecutor, shellMainHandler,
                 new SyncExecutor(), taskViewTransitions, transitions,
                 syncQueue, wmService, bubbleProperties);
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceLayout.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceLayout.kt
index 843afb8..a075d0d 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceLayout.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceLayout.kt
@@ -13,7 +13,6 @@
  */
 package com.android.systemui.plugins.clocks
 
-import android.content.Context
 import android.util.DisplayMetrics
 import android.view.View
 import androidx.constraintlayout.widget.ConstraintSet
@@ -27,6 +26,8 @@
 import com.android.systemui.plugins.annotations.GeneratedImport
 import com.android.systemui.plugins.annotations.ProtectedInterface
 import com.android.systemui.plugins.annotations.ProtectedReturn
+import com.android.systemui.plugins.clocks.ContextExt.getDimen
+import com.android.systemui.plugins.clocks.ContextExt.getId
 
 /** Specifies layout information for the clock face */
 @ProtectedInterface
@@ -94,18 +95,18 @@
             constraints: ConstraintSet,
         ): ConstraintSet {
             constraints.apply {
-                val context = clockPreviewConfig.previewContext
-                val lockscreenClockViewLargeId = getId(context, "lockscreen_clock_view_large")
+                val context = clockPreviewConfig.context
+                val lockscreenClockViewLargeId = context.getId("lockscreen_clock_view_large")
                 constrainWidth(lockscreenClockViewLargeId, WRAP_CONTENT)
                 constrainHeight(lockscreenClockViewLargeId, WRAP_CONTENT)
                 constrainMaxHeight(lockscreenClockViewLargeId, 0)
 
                 val largeClockTopMargin =
                     SystemBarUtils.getStatusBarHeight(context) +
-                        getDimen(context, "small_clock_padding_top") +
-                        getDimen(context, "keyguard_smartspace_top_offset") +
-                        getDimen(context, "date_weather_view_height") +
-                        getDimen(context, "enhanced_smartspace_height")
+                        context.getDimen("small_clock_padding_top") +
+                        context.getDimen("keyguard_smartspace_top_offset") +
+                        context.getDimen("date_weather_view_height") +
+                        context.getDimen("enhanced_smartspace_height")
                 connect(lockscreenClockViewLargeId, TOP, PARENT_ID, TOP, largeClockTopMargin)
                 connect(lockscreenClockViewLargeId, START, PARENT_ID, START)
                 connect(lockscreenClockViewLargeId, END, PARENT_ID, END)
@@ -119,7 +120,7 @@
                     connect(lockscreenClockViewLargeId, BOTTOM, lockId, TOP)
                 }
                     ?: run {
-                        val bottomPaddingPx = getDimen(context, "lock_icon_margin_bottom")
+                        val bottomPaddingPx = context.getDimen("lock_icon_margin_bottom")
                         val defaultDensity =
                             DisplayMetrics.DENSITY_DEVICE_STABLE.toFloat() /
                                 DisplayMetrics.DENSITY_DEFAULT.toFloat()
@@ -134,52 +135,22 @@
                         )
                     }
 
-                val smallClockViewId = getId(context, "lockscreen_clock_view")
+                val smallClockViewId = context.getId("lockscreen_clock_view")
                 constrainWidth(smallClockViewId, WRAP_CONTENT)
-                constrainHeight(smallClockViewId, getDimen(context, "small_clock_height"))
+                constrainHeight(smallClockViewId, context.getDimen("small_clock_height"))
                 connect(
                     smallClockViewId,
                     START,
                     PARENT_ID,
                     START,
-                    getDimen(context, "clock_padding_start") +
-                        getDimen(context, "status_view_margin_horizontal"),
+                    context.getDimen("clock_padding_start") +
+                        context.getDimen("status_view_margin_horizontal"),
                 )
-                val smallClockTopMargin =
-                    getSmallClockTopPadding(
-                        clockPreviewConfig = clockPreviewConfig,
-                        SystemBarUtils.getStatusBarHeight(context),
-                    )
+
+                val smallClockTopMargin = clockPreviewConfig.getSmallClockTopPadding()
                 connect(smallClockViewId, TOP, PARENT_ID, TOP, smallClockTopMargin)
             }
             return constraints
         }
-
-        fun getId(context: Context, name: String): Int {
-            val packageName = context.packageName
-            val res = context.packageManager.getResourcesForApplication(packageName)
-            val id = res.getIdentifier(name, "id", packageName)
-            return id
-        }
-
-        fun getDimen(context: Context, name: String): Int {
-            val packageName = context.packageName
-            val res = context.resources
-            val id = res.getIdentifier(name, "dimen", packageName)
-            return if (id == 0) 0 else res.getDimensionPixelSize(id)
-        }
-
-        fun getSmallClockTopPadding(
-            clockPreviewConfig: ClockPreviewConfig,
-            statusBarHeight: Int,
-        ): Int {
-            return if (clockPreviewConfig.isShadeLayoutWide) {
-                getDimen(clockPreviewConfig.previewContext, "keyguard_split_shade_top_margin") -
-                    if (clockPreviewConfig.isSceneContainerFlagEnabled) statusBarHeight else 0
-            } else {
-                getDimen(clockPreviewConfig.previewContext, "keyguard_clock_top_margin") +
-                    if (!clockPreviewConfig.isSceneContainerFlagEnabled) statusBarHeight else 0
-            }
-        }
     }
 }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPreviewConfig.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPreviewConfig.kt
index 94e669f..c705c51 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPreviewConfig.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPreviewConfig.kt
@@ -17,10 +17,24 @@
 package com.android.systemui.plugins.clocks
 
 import android.content.Context
+import com.android.internal.policy.SystemBarUtils
+import com.android.systemui.plugins.clocks.ContextExt.getDimen
 
 data class ClockPreviewConfig(
-    val previewContext: Context,
+    val context: Context,
     val isShadeLayoutWide: Boolean,
     val isSceneContainerFlagEnabled: Boolean = false,
     val lockId: Int? = null,
-)
+) {
+    fun getSmallClockTopPadding(
+        statusBarHeight: Int = SystemBarUtils.getStatusBarHeight(context)
+    ): Int {
+        return if (isShadeLayoutWide) {
+            context.getDimen("keyguard_split_shade_top_margin") -
+                if (isSceneContainerFlagEnabled) statusBarHeight else 0
+        } else {
+            context.getDimen("keyguard_clock_top_margin") +
+                if (!isSceneContainerFlagEnabled) statusBarHeight else 0
+        }
+    }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ContextExt.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ContextExt.kt
new file mode 100644
index 0000000..17a1bfc
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ContextExt.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 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.plugins.clocks
+
+import android.content.Context
+
+object ContextExt {
+    fun Context.getId(name: String): Int {
+        val res = packageManager.getResourcesForApplication(packageName)
+        return res.getIdentifier(name, "id", packageName)
+    }
+
+    fun Context.getDimen(name: String): Int {
+        val id = resources.getIdentifier(name, "dimen", packageName)
+        return if (id == 0) 0 else resources.getDimensionPixelSize(id)
+    }
+}
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 41c3e06..83a607b 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -42,7 +42,7 @@
     <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>
     <string name="keyguard_accessibility_pin_area" msgid="7403009340414014734">"PIN kodearen eremua"</string>
-    <string name="keyguard_accessibility_password" msgid="3524161948484801450">"Gailuaren pasahitza"</string>
+    <string name="keyguard_accessibility_password" msgid="3524161948484801450">"Gailuko pasahitza"</string>
     <string name="keyguard_accessibility_sim_pin_area" msgid="6272116591533888062">"SIM txartelaren PIN kodearen eremua"</string>
     <string name="keyguard_accessibility_sim_puk_area" msgid="5537294043180237374">"SIM txartelaren PUK kodearen eremua"</string>
     <string name="keyboardview_keycode_delete" msgid="8489719929424895174">"Ezabatu"</string>
diff --git a/packages/SystemUI/res-product/values-ar/strings.xml b/packages/SystemUI/res-product/values-ar/strings.xml
index 7332ec8..a25e8c1 100644
--- a/packages/SystemUI/res-product/values-ar/strings.xml
+++ b/packages/SystemUI/res-product/values-ar/strings.xml
@@ -66,8 +66,6 @@
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"يمكنك فتح قفل جهازك للوصول إلى مزيد من الخيارات."</string>
     <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"جارٍ تشغيل الوسائط على هذا الهاتف."</string>
     <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"جارٍ تشغيل الوسائط على هذا الجهاز اللوحي."</string>
-    <!-- no translation found for finder_active (2734050945122991747) -->
-    <skip />
-    <!-- no translation found for finder_active (8045583079989970505) -->
-    <skip />
+    <string name="finder_active" product="default" msgid="2734050945122991747">"يمكنك تحديد مكان هذا الهاتف باستخدام تطبيق \"العثور على جهازي\" حتى عندما يكون مُطفأً"</string>
+    <string name="finder_active" product="tablet" msgid="8045583079989970505">"يمكنك تحديد مكان هذا الجهاز اللوحي باستخدام تطبيق \"العثور على جهازي\" حتى عندما يكون مُطفأً"</string>
 </resources>
diff --git a/packages/SystemUI/res-product/values-hi/strings.xml b/packages/SystemUI/res-product/values-hi/strings.xml
index 92d5505..67bc2a3 100644
--- a/packages/SystemUI/res-product/values-hi/strings.xml
+++ b/packages/SystemUI/res-product/values-hi/strings.xml
@@ -66,8 +66,6 @@
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ज़्यादा विकल्प देखने के लिए, अपना डिवाइस अनलॉक करें"</string>
     <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"मीडिया इस फ़ोन पर चल रहा है"</string>
     <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"मीडिया इस टैबलेट पर चल रहा है"</string>
-    <!-- no translation found for finder_active (2734050945122991747) -->
-    <skip />
-    <!-- no translation found for finder_active (8045583079989970505) -->
-    <skip />
+    <string name="finder_active" product="default" msgid="2734050945122991747">"आप Find My Device की मदद से, इस फ़ोन के बंद होने पर भी इसकी जगह की जानकारी का पता लगा सकते हैं"</string>
+    <string name="finder_active" product="tablet" msgid="8045583079989970505">"आप Find My Device की मदद से, इस टैबलेट के बंद होने पर भी इसकी जगह की जानकारी का पता लगा सकते हैं"</string>
 </resources>
diff --git a/packages/SystemUI/res-product/values-pt-rBR/strings.xml b/packages/SystemUI/res-product/values-pt-rBR/strings.xml
index 1a99a16..f21bbd0 100644
--- a/packages/SystemUI/res-product/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-product/values-pt-rBR/strings.xml
@@ -66,6 +66,6 @@
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloqueie seu dispositivo para ver mais opções"</string>
     <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Tocando neste smartphone"</string>
     <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Mídia tocando neste tablet"</string>
-    <string name="finder_active" product="default" msgid="2734050945122991747">"Localize o smartphone com o Encontre Meu Dispositivo mesmo se ele estiver desligado"</string>
-    <string name="finder_active" product="tablet" msgid="8045583079989970505">"Localize o tablet com o Encontre Meu Dispositivo mesmo se ele estiver desligado"</string>
+    <string name="finder_active" product="default" msgid="2734050945122991747">"Você pode localizar o smartphone com o Encontre Meu Dispositivo mesmo se ele estiver desligado"</string>
+    <string name="finder_active" product="tablet" msgid="8045583079989970505">"Você pode localizar o tablet com o Encontre Meu Dispositivo mesmo se ele estiver desligado"</string>
 </resources>
diff --git a/packages/SystemUI/res-product/values-pt/strings.xml b/packages/SystemUI/res-product/values-pt/strings.xml
index 1a99a16..f21bbd0 100644
--- a/packages/SystemUI/res-product/values-pt/strings.xml
+++ b/packages/SystemUI/res-product/values-pt/strings.xml
@@ -66,6 +66,6 @@
     <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloqueie seu dispositivo para ver mais opções"</string>
     <string name="media_transfer_playing_this_device" product="default" msgid="5795784619523545556">"Tocando neste smartphone"</string>
     <string name="media_transfer_playing_this_device" product="tablet" msgid="222514408550408633">"Mídia tocando neste tablet"</string>
-    <string name="finder_active" product="default" msgid="2734050945122991747">"Localize o smartphone com o Encontre Meu Dispositivo mesmo se ele estiver desligado"</string>
-    <string name="finder_active" product="tablet" msgid="8045583079989970505">"Localize o tablet com o Encontre Meu Dispositivo mesmo se ele estiver desligado"</string>
+    <string name="finder_active" product="default" msgid="2734050945122991747">"Você pode localizar o smartphone com o Encontre Meu Dispositivo mesmo se ele estiver desligado"</string>
+    <string name="finder_active" product="tablet" msgid="8045583079989970505">"Você pode localizar o tablet com o Encontre Meu Dispositivo mesmo se ele estiver desligado"</string>
 </resources>
diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml
index 9c1dc64..6f8b4cd 100644
--- a/packages/SystemUI/res/layout/media_output_dialog.xml
+++ b/packages/SystemUI/res/layout/media_output_dialog.xml
@@ -120,36 +120,6 @@
     </LinearLayout>
 
     <LinearLayout
-        android:id="@+id/cast_app_section"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="20dp"
-        android:layout_marginStart="@dimen/dialog_side_padding"
-        android:layout_marginEnd="@dimen/dialog_side_padding"
-        android:layout_marginBottom="@dimen/dialog_bottom_padding"
-        android:orientation="vertical"
-        android:visibility="gone">
-        <TextView
-            android:id="@+id/launch_app_title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical|start"
-            android:ellipsize="end"
-            android:textColor="?android:attr/textColorPrimary"
-            android:text="@string/media_output_dialog_launch_app_text"
-            android:maxLines="1"
-            android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
-            android:textSize="16sp"/>
-
-        <Button
-            android:id="@+id/launch_app_button"
-            style="@style/Widget.Dialog.Button.BorderButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:drawablePadding="5dp"/>
-    </LinearLayout>
-
-    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginTop="4dp"
diff --git a/packages/SystemUI/res/layout/ongoing_activity_chip.xml b/packages/SystemUI/res/layout/ongoing_activity_chip_content.xml
similarity index 84%
rename from packages/SystemUI/res/layout/ongoing_activity_chip.xml
rename to packages/SystemUI/res/layout/ongoing_activity_chip_content.xml
index 51217d4..6f42286 100644
--- a/packages/SystemUI/res/layout/ongoing_activity_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_activity_chip_content.xml
@@ -13,17 +13,11 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<!-- Have the wrapper frame layout match the parent height so that we get a larger touch area for
-     the chip. -->
-<FrameLayout
+
+<merge
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="match_parent"
-    android:layout_gravity="center_vertical|start"
-    android:layout_marginStart="5dp"
->
-    <!-- TODO(b/332662551): Update this content description when this supports more than just
-         phone calls. -->
+    >
+
     <com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
         android:id="@+id/ongoing_activity_chip_background"
         android:layout_width="wrap_content"
@@ -39,7 +33,7 @@
         <ImageView
             android:src="@*android:drawable/ic_phone"
             android:id="@+id/ongoing_activity_chip_icon"
-            android:contentDescription="@string/ongoing_phone_call_content_description"
+            android:contentDescription="@string/ongoing_call_content_description"
             android:layout_width="@dimen/ongoing_activity_chip_icon_size"
             android:layout_height="@dimen/ongoing_activity_chip_icon_size"
             android:tint="?android:attr/colorPrimary"
@@ -72,4 +66,4 @@
             />
 
     </com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer>
-</FrameLayout>
+</merge>
diff --git a/packages/SystemUI/res/layout/ongoing_activity_chip_primary.xml b/packages/SystemUI/res/layout/ongoing_activity_chip_primary.xml
new file mode 100644
index 0000000..114fe6c
--- /dev/null
+++ b/packages/SystemUI/res/layout/ongoing_activity_chip_primary.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2024 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.
+  -->
+
+<FrameLayout
+    style="@style/StatusBar.Chip.RootView">
+
+    <include layout="@layout/ongoing_activity_chip_content" />
+
+</FrameLayout>
+
diff --git a/packages/SystemUI/res/layout/ongoing_activity_chip_secondary.xml b/packages/SystemUI/res/layout/ongoing_activity_chip_secondary.xml
new file mode 100644
index 0000000..81a7822
--- /dev/null
+++ b/packages/SystemUI/res/layout/ongoing_activity_chip_secondary.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2024 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.
+  -->
+
+<com.android.systemui.statusbar.chips.ui.view.SecondaryOngoingActivityChip
+    style="@style/StatusBar.Chip.RootView">
+
+    <include layout="@layout/ongoing_activity_chip_content" />
+
+</com.android.systemui.statusbar.chips.ui.view.SecondaryOngoingActivityChip>
+
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index 1f4dea9..e4da472 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -103,10 +103,10 @@
                         android:gravity="center_vertical|start"
                     />
 
-                    <include layout="@layout/ongoing_activity_chip"
+                    <include layout="@layout/ongoing_activity_chip_primary"
                         android:id="@+id/ongoing_activity_chip_primary"/>
 
-                    <include layout="@layout/ongoing_activity_chip"
+                    <include layout="@layout/ongoing_activity_chip_secondary"
                         android:id="@+id/ongoing_activity_chip_secondary"
                         android:visibility="gone"/>
 
diff --git a/packages/SystemUI/res/layout/status_bar_notification_shelf.xml b/packages/SystemUI/res/layout/status_bar_notification_shelf.xml
index 58c5450..071b076 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_shelf.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_shelf.xml
@@ -24,11 +24,11 @@
     android:clickable="true"
     >
 
-    <com.android.systemui.statusbar.notification.row.NotificationBackgroundView
+    <com.android.systemui.statusbar.notification.shelf.NotificationShelfBackgroundView
         android:id="@+id/backgroundNormal"
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
-    <com.android.systemui.statusbar.phone.NotificationIconContainer
+    <com.android.systemui.statusbar.notification.shelf.NotificationShelfIconContainer
         android:id="@+id/content"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index bad5711..3270759 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -33,15 +33,25 @@
         app:layout_constraintStart_toStartOf="@id/volume_dialog_main_slider_container"
         app:layout_constraintTop_toTopOf="@id/volume_ringer_drawer" />
 
+    <View
+        android:id="@+id/volume_ringer_horizontal_background"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="@drawable/volume_dialog_background"
+        app:layout_constraintBottom_toTopOf="@id/volume_dialog_main_slider_container"
+        app:layout_constraintEnd_toEndOf="@id/volume_ringer_drawer"
+        app:layout_constraintStart_toStartOf="@id/volume_ringer_drawer"
+        app:layout_constraintTop_toTopOf="@id/volume_dialog_background" />
+
     <include
         android:id="@id/volume_ringer_drawer"
         layout="@layout/volume_ringer_drawer"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginBottom="@dimen/volume_dialog_components_spacing"
+        android:layout_marginRight="@dimen/volume_dialog_ringer_drawer_diff_right_margin"
         app:layout_constraintBottom_toTopOf="@id/volume_dialog_main_slider_container"
         app:layout_constraintEnd_toEndOf="@id/volume_dialog_main_slider_container"
-        app:layout_constraintStart_toStartOf="@id/volume_dialog_main_slider_container"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintVertical_bias="1" />
 
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 72b57ca..ebc1935 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Deurlopende kennisgewing vir \'n skermopnamesessie"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Neem jou skerm op?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Neem een app op"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Neem hele skerm op"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Neem hele skerm op: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Wanneer jy jou hele skerm opneem, word enigiets wat op jou skerm wys, opgeneem. Wees dus versigtig met dinge soos wagwoorde, betalingbesonderhede, boodskappe, foto’s, en oudio en video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Wanneer jy ’n app opneem, word enigiets wat in daardie app gewys of gespeel word, opgeneem. Wees dus versigtig met dinge soos wagwoorde, betalingbesonderhede, boodskappe, foto’s, en oudio en video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Neem skerm op"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Kon nie voorafstelling opdateer nie"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voorafstelling"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Gekies"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nutsgoed"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Intydse Onderskrifte"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Wys laeprioriteit-kennisgewingikone"</string>
     <string name="other" msgid="429768510980739978">"Ander"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"verwyder teël"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"voeg teël aan einde by"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Skuif teël"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Voeg teël by"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Skuif na <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Voeg by posisie <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posisie is ongeldig."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"kies gebruiker"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Geen internet nie"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Maak <xliff:g id="ID_1">%s</xliff:g>-instellings oop."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Wysig volgorde van instellings."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Aan/af-kieslys"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Bladsy <xliff:g id="ID_1">%1$d</xliff:g> van <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Sluitskerm"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ontkoppel)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan nie wissel nie. Tik om weer te probeer."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Koppel ’n toestel"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Maak die app oop om hierdie sessie uit te saai."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Hou op uitsaai"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Beskikbare toestelle vir oudio-uitsette."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Gaan na tuisskerm"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Bekyk onlangse apps"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Klaar"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Probeer weer!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Gaan terug"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Swiep links of regs met drie vingers op jou raakpaneel"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Mooi so!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Jy het die Gaan Terug-gebaar voltooi."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Swiep links of regs met drie vingers om terug te gaan met jou raakpaneel"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Gaan na tuisskerm"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Swiep op met drie vingers op jou raakpaneel"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Uitstekende werk!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Jy het die Gaan na Tuisskerm-gebaar voltooi"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Swiep op met drie vingers op jou raakpaneel om na jou tuisskerm te gaan"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Bekyk onlangse apps"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Swiep op en hou met drie vingers op jou raakpaneel"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Knap gedaan!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Jy het die Bekyk Onlangse Apps-gebaar voltooi."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Swiep op en hou met drie vingers op jou raakpaneel om onlangse apps te bekyk"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Bekyk alle apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Druk die handelingsleutel op jou sleutelbord"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Welgedaan!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Jy het die Bekyk Onlangse Apps-gebaar voltooi"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Druk die handelingsleutel op jou sleutelbord om al jou apps te bekyk"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Tutoriaalanimasie; klik om te onderbreek of hervat om te speel."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Sleutelbordlig"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Vlak %1$d van %2$d"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 586c204..18bffac 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ለአንድ የማያ ገፅ ቀረጻ ክፍለ-ጊዜ በመካሄድ ያለ ማሳወቂያ"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ማያ ገፅዎን ይቀዳሉ?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"አንድ መተግበሪያ ቅዳ"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"መላው ማያ ገፅን ቅረጽ"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ሙሉ ማያ ገፅን ቅዳ፦ %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"መላው ማያ ገፅዎን በሚቀዱበት ጊዜ፣ በማያ ገፅዎ ላይ የሚታየው ማንኛውም ነገር ይቀዳል። ስለዚህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ መልዕክቶች፣ ፎቶዎች እና ኦዲዮ እና ቪድዮ ላሉ ነገሮች ጥንቃቄ ያድርጉ።"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"መተግበሪያን ሲቀዱ በዚያ መተግበሪያ ውስጥ የሚታይ ወይም የሚጫወት ማንኛውም ነገር ይቀዳል። ስለዚህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ መልዕክቶች፣ ፎቶዎች እና ኦዲዮ እና ቪድዮ ላሉ ነገሮች ጥንቃቄ ያድርጉ።"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ማያ ገፅን ቅረጽ"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ቅድመ-ቅምጥን ማዘመን አልተቻለም"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ቅድመ-ቅምጥ"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ተመርጧል"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"መሣሪያዎች"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"የቀጥታ መግለጫ ጽሑፍ"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"ማስታወሻ"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"አነስተኛ ቅድሚያ ያላቸው የማሳወቂያ አዶዎችን አሳይ"</string>
     <string name="other" msgid="429768510980739978">"ሌላ"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ሰቅ አስወግድ"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ሰቅ መጨረሻው ላይ አክል"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ሰቁን ውሰድ"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"ሰቅ ያክሉ"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"ወደ <xliff:g id="POSITION">%1$d</xliff:g> ውሰድ"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"ወደ <xliff:g id="POSITION">%1$d</xliff:g> ቦታ አክል"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"አቀማመጡ ተቀባይነት የለውም።"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ተጠቃሚ ይምረጡ"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ምንም በይነመረብ የለም"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"የ<xliff:g id="ID_1">%s</xliff:g> ቅንብሮችን ክፈት።"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"የቅንብሮድ ቅደም-ተከተል አርትዕ።"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"የኃይል ምናሌ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ገፅ <xliff:g id="ID_1">%1$d</xliff:g> ከ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ማያ ገፅ ቁልፍ"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ተቋርጧል)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"መቀየር አይቻልም። እንደገና ለመሞከር መታ ያድርጉ።"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"አንድ መሣሪያ ያገናኙ"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ይህን ክፍለ ጊዜ cast ለማድረግ፣ እባክዎ መተግበሪያውን ይክፈቱ።"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"የማይታወቅ መተግበሪያ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Cast ማድረግ አቁም"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ለኦዲዮ ውጽዓት ተገኚ የሆኑ መሣሪያዎች"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"ወደ መነሻ ሂድ"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"የቅርብ ጊዜ መተግበሪያዎችን አሳይ"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ተከናውኗል"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"እንደገና ይሞክሩ!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ወደኋላ ተመለስ"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"የመዳሰሻ ሰሌዳዎ ላይ ሦስት ጣቶችን በመጠቀም ወደ ግራ ወይም ወደ ቀኝ ያንሸራትቱ"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"አሪፍ!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"ወደኋላ የመመለስ ምልክትን አጠናቅቀዋል።"</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"የመዳሰሻ ሰሌዳዎን ወደመጠቀም ለመመለስ ሦስት ጣቶችን በመጠቀም ወደ ግራ ወይም ወደ ቀኝ ያንሸራትቱ"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"ወደ መነሻ ሂድ"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"በመዳሰሻ ሰሌዳዎ ላይ በሦስት ጣቶች ወደ ላይ ያንሸራትቱ"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"ጥሩ ሥራ!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"ወደ መነሻ ሂድ ምልክትን አጠናቅቀዋል"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"ወደ መነሻ ማያ ገፅዎ ለመሄድ የመዳሰሻ ሰሌዳዎ ላይ በሦስት ጣቶች ወደ ላይ ያንሸራትቱ"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"የቅርብ ጊዜ መተግበሪያዎችን አሳይ"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"የመዳሰሻ ሰሌዳዎ ላይ ሦስት ጣቶችን በመጠቀም ወደላይ ያንሸራትቱ እና ይያዙ"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"ጥሩ ሠርተዋል!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"የቅርብ ጊዜ መተግበሪያዎች አሳይ ምልክትን አጠናቅቀዋል።"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"የቅርብ ጊዜ መተግበሪያዎችን ለማየት የመዳሰሻ ሰሌዳዎ ላይ ሦስት ጣቶችን በመጠቀም ወደላይ ያንሸራትቱ እና ይያዙ"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"ሁሉንም መተግበሪያዎች ይመልከቱ"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"በቁልፍ ሰሌዳዎ ላይ ያለውን የተግባር ቁልፍ ይጫኑ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ጥሩ ሠርተዋል!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"የሁሉንም መተግበሪያዎች አሳይ ምልክትን አጠናቅቀዋል"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"ሁሉንም መተግበሪያዎችዎን ለማየት በቁልፍ ሰሌዳዎ ላይ ያለውን የድርጊት ቁልፍ ይጫኑ"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"የአጋዥ ሥልጠና እነማ፣ ማጫወትን ባለበት ለማቆም እና ከቆመበት ለመቀጠል ጠቅ ያድርጉ።"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"የቁልፍ ሰሌዳ የጀርባ ብርሃን"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"ደረጃ %1$d ከ %2$d"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 92d0cbb..20668f8 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"إشعار مستمر لجلسة تسجيل شاشة"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"هل تريد تسجيل الشاشة؟"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"تسجيل شاشة تطبيق واحد"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"تسجيل الشاشة بكاملها"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"‏تسجيل محتوى الشاشة بالكامل: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"أثناء تسجيل محتوى الشاشة بالكامل، يتم تسجيل كل المحتوى المعروض على شاشتك، لذا يُرجى توخي الحذر بشأن المعلومات الظاهرة، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور والمقاطع الصوتية والفيديوهات."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"سيتم تسجيل كل المحتوى المعروض أو المشغَّل على شاشة التطبيق، لذا يُرجى توخي الحذر بشأن المعلومات الظاهرة، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور والمقاطع الصوتية والفيديوهات."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"تسجيل الشاشة"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"تعذَّر تعديل الإعداد المسبق"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"الإعدادات المسبقة"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"تمّ اختياره"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"الأدوات"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"النسخ النصي التلقائي"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"ملاحظات"</string>
@@ -753,20 +769,13 @@
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"قمر صناعي، الاتصال متوفّر"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"اتصالات الطوارئ بالقمر الصناعي"</string>
     <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"مكالمات الطوارئ أو ميزة \"اتصالات طوارئ بالقمر الصناعي\""</string>
-    <!-- no translation found for accessibility_phone_string_format (7798841417881811812) -->
-    <skip />
-    <!-- no translation found for accessibility_no_signal (7052827511409250167) -->
-    <skip />
-    <!-- no translation found for accessibility_one_bar (5342012847647834506) -->
-    <skip />
-    <!-- no translation found for accessibility_two_bars (122628483354508429) -->
-    <skip />
-    <!-- no translation found for accessibility_three_bars (5143286602926069024) -->
-    <skip />
-    <!-- no translation found for accessibility_four_bars (8838495563822541844) -->
-    <skip />
-    <!-- no translation found for accessibility_signal_full (1519655809806462972) -->
-    <skip />
+    <string name="accessibility_phone_string_format" msgid="7798841417881811812">"‫\"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>\"، <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>"</string>
+    <string name="accessibility_no_signal" msgid="7052827511409250167">"ما مِن أشرطة إشارة"</string>
+    <string name="accessibility_one_bar" msgid="5342012847647834506">"شريط إشارة واحد"</string>
+    <string name="accessibility_two_bars" msgid="122628483354508429">"شريطا إشارة"</string>
+    <string name="accessibility_three_bars" msgid="5143286602926069024">"ثلاثة أشرطة إشارة"</string>
+    <string name="accessibility_four_bars" msgid="8838495563822541844">"أربعة أشرطة إشارة"</string>
+    <string name="accessibility_signal_full" msgid="1519655809806462972">"شريط إشارة كاملة"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"ملف العمل"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"متعة للبعض وليس للجميع"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"‏توفر لك أداة ضبط واجهة مستخدم النظام طرقًا إضافية لتعديل واجهة مستخدم Android وتخصيصها. ويمكن أن تطرأ تغييرات على هذه الميزات التجريبية أو يمكن أن تتعطل هذه الميزات أو تختفي في الإصدارات المستقبلية. عليك متابعة الاستخدام مع توخي الحذر."</string>
@@ -967,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"إظهار رموز الإشعارات ذات الأولوية المنخفضة"</string>
     <string name="other" msgid="429768510980739978">"غير ذلك"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"إزالة بطاقة"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"إضافة بطاقة إلى نهاية الإعدادات السريعة"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"نقل بطاقة"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"إضافة بطاقة"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"الانتقال إلى <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"الإضافة إلى الموضع <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"الموضِع غير صالح."</string>
@@ -985,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"اختيار مستخدم"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"لا يتوفر اتصال إنترنت."</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"فتح إعدادات <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"تعديل ترتيب الإعدادات."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"قائمة زر التشغيل"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"الصفحة <xliff:g id="ID_1">%1$d</xliff:g> من <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"شاشة القفل"</string>
@@ -1216,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(غير متّصل)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"لا يمكن التبديل. انقر لإعادة المحاولة."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"ربط جهاز"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"لبث هذه الجلسة، يُرجى فتح التطبيق"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"تطبيق غير معروف"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"إيقاف البث"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"الأجهزة المتاحة لإخراج الصوت"</string>
@@ -1475,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"الانتقال إلى الصفحة الرئيسية"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"عرض التطبيقات المستخدَمة مؤخرًا"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"تم"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"يُرجى إعادة المحاولة"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"رجوع"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"مرِّر سريعًا لليمين أو لليسار باستخدام 3 أصابع على لوحة اللمس"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"أحسنت."</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"لقد أكملت التدريب على إيماءة الرجوع."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"للرجوع باستخدام لوحة اللمس، يُرجى التمرير سريعًا لليمين أو لليسار باستخدام ثلاثة أصابع"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"الانتقال إلى الشاشة الرئيسية"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"مرّر سريعًا للأعلى باستخدام 3 أصابع على لوحة اللمس"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"أحسنت صنعًا."</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"لقد أكملت الدليل التوجيهي عن إيماءة \"الانتقال إلى الشاشة الرئيسية\""</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"يُرجى التمرير سريعًا للأعلى باستخدام ثلاثة أصابع على لوحة اللمس للانتقال إلى الشاشة الرئيسية"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"عرض التطبيقات المستخدَمة مؤخرًا"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"مرِّر سريعًا للأعلى مع الاستمرار باستخدام 3 أصابع على لوحة اللمس"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"أحسنت."</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"لقد أكملْت التدريب على إيماءة عرض التطبيقات المستخدَمة مؤخرًا."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"لعرض التطبيقات المستخدَمة مؤخرًا، يُرجى التمرير سريعًا للأعلى مع الاستمرار باستخدام ثلاثة أصابع على لوحة اللمس"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"عرض جميع التطبيقات"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"اضغط على مفتاح الإجراء في لوحة المفاتيح"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"أحسنت!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"لقد أكملْت التدريب على إيماءة عرض جميع التطبيقات"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"يمكنك الضغط على مفتاح الإجراء في لوحة المفاتيح لعرض جميع التطبيقات"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"صورة متحركة للدليل التوجيهي: يمكنك النقر عليها لإيقاف تشغيلها مؤقتًا واستئنافه."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"الإضاءة الخلفية للوحة المفاتيح"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏مستوى الإضاءة: %1$d من %2$d"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 89e5083..fb0030f 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রীন ৰেকৰ্ডিং ছেশ্বন চলি থকা সময়ত পোৱা জাননী"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"আপোনাৰ স্ক্ৰীনখন ৰেকৰ্ড কৰিবনে?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"এটা এপ্ ৰেকৰ্ড কৰক"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"গোটেই স্ক্ৰীনখন ৰেকৰ্ড কৰক"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"গোটেই স্ক্ৰীনখন ৰেকৰ্ড কৰক: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"আপুনি গোটেই স্ক্ৰীনখন ৰেকৰ্ডিং কৰিলে, আপোনাৰ স্ক্ৰীনখনত দেখুওৱা যিকোনো বস্তু ৰেকৰ্ড কৰা হয়। গতিকে, পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা, ফট’ আৰু অডিঅ’ আৰু ভিডিঅ’ৰ ক্ষেত্ৰত সাৱধান হওক।"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"আপুনি কোনো এপ্ ৰেকৰ্ড কৰিলে, সেই এপত দেখুওৱা বা প্লে’ কৰা যিকোনো বস্তু ৰেকৰ্ড কৰা হয়। গতিকে, পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা, ফট’ আৰু অডিঅ’ আৰু ভিডিঅ’ৰ ক্ষেত্ৰত সাৱধান হওক।"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"স্ক্ৰীনখন ৰেকৰ্ড কৰক"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"প্ৰিছেট আপডে’ট কৰিব পৰা নগ’ল"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"প্ৰিছেট"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"বাছনি কৰা হৈছে"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"সঁজুলি"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"লাইভ কেপশ্বন"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"টোকা"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"কম গুৰুত্বপূৰ্ণ জাননীৰ আইকনসমূহ দেখুৱাওক"</string>
     <string name="other" msgid="429768510980739978">"অন্যান্য"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"টাইল আঁতৰাবলৈ"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"টাইল শেষত যোগ দিবলৈ"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"টাইল স্থানান্তৰ কৰক"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"টাইল যোগ দিয়ক"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> নম্বৰলৈ স্থানান্তৰ কৰক"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> নম্বৰ স্থানত যোগ দিয়ক"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"স্থান অমান্য।"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ব্যৱহাৰকাৰী বাছনি কৰক"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ইণ্টাৰনেট সংযোগ নাই"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g>ৰ ছেটিং খোলক।"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ছেটিঙৰ ক্ৰম সম্পাদনা কৰক।"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"পাৱাৰ মেনু"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>ৰ পৃষ্ঠা <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"লক স্ক্ৰীন"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(সংযোগ বিচ্ছিন্ন কৰা হৈছে)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"সলনি কৰিব নোৱাৰি। আকৌ চেষ্টা কৰিবলৈ টিপক।"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"ডিভাইচ সংযোগ কৰক"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"এই ছেশ্বনটো কাষ্ট কৰিবলৈ, অনুগ্ৰহ কৰি এপ্‌টো খোলক"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"অজ্ঞাত এপ্"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"কাষ্ট বন্ধ কৰক"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"অডিঅ\' আউটপুটৰ বাবে উপলব্ধ ডিভাইচ।"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"গৃহ পৃষ্ঠালৈ যাওক"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"শেহতীয়া এপ্‌সমূহ চাওক"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"হ’ল"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"পুনৰ চেষ্টা কৰক!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"উভতি যাওক"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"আপোনাৰ টাচ্চপেডত তিনিটা আঙুলি ব্যৱহাৰ কৰি বাওঁফাললৈ বা সোঁফাললৈ ছোৱাইপ কৰক"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"সুন্দৰ!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"আপুনি উভতি যোৱাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে।"</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"আপোনাৰ টাচ্চপেড ব্যৱহাৰ কৰি উভতি যাবলৈ, তিনিটা আঙুলি ব্যৱহাৰ কৰি বাওঁ বা সোঁফালে ছোৱাইপ কৰক"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"গৃহ পৃষ্ঠালৈ যাওক"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"আপোনাৰ টাচ্চপেডত তিনিটা আঙুলিৰে ওপৰলৈ ছোৱাইপ কৰক"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"বঢ়িয়া!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"আপুনি গৃহ স্ক্ৰীনলৈ যোৱাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"আপোনাৰ গৃহ স্ক্ৰীনলৈ যাবলৈ আপোনাৰ টাচ্চপেডত তিনিটা আঙুলিৰে ওপৰলৈ ছোৱাইপ কৰক"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"শেহতীয়া এপ্‌সমূহ চাওক"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"আপোনাৰ টাচ্চপেডত তিনিটা আঙুলি ব্যৱহাৰ কৰি ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"বঢ়িয়া!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"আপুনি শেহতীয়া এপ্ চোৱাৰ নিৰ্দেশনাটো সম্পূৰ্ণ কৰিছে।"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"শেহতীয়া এপ্‌সমূহ চাবলৈ, আপোনাৰ টাচ্চপেডত তিনিটা আঙুলি ব্যৱহাৰ কৰি ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"আটাইবোৰ এপ্ চাওক"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"আপোনাৰ কীব’ৰ্ডৰ কাৰ্য কীটোত টিপক"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"বঢ়িয়া!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"আপুনি আটাইবোৰ এপ্ চোৱাৰ নিৰ্দেশনাটো সম্পূৰ্ণ কৰিছে"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"আপোনাৰ আটাইবোৰ এপ্‌ চাবলৈ আপোনাৰ কীব’ৰ্ডত কাৰ্য কীটো টিপক"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"টিউট’ৰিয়েল এনিমেশ্বন, পজ কৰিবলৈ আৰু প্লে’ কৰাটো পুনৰ আৰম্ভ কৰিবলৈ ক্লিক কৰক।"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"কীব’ৰ্ডৰ বেকলাইট"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dৰ %1$d স্তৰ"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 31238d0..532fceb 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekranın video çəkimi ərzində silinməyən bildiriş"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ekran qeydə alınsın?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Bir tətbiqi qeydə alın"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Bütün ekranı qeydə alın"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Bütün ekranı qeydə alın: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Bütün ekranı qeydə alarkən ekranda göstərilən bütün kontent qeydə alınır. Parol, ödəniş detalları, mesaj, foto, habelə audio və video kimi məlumatlarla bağlı diqqətli olun."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Tətbiq qeydə aldıqda həmin tətbiqdə göstərilən və ya işə salınan bütün kontent qeydə alınır. Parol, ödəniş detalları, mesaj, foto, habelə audio və video kimi məlumatlarla bağlı diqqətli olun."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekranı qeydə alın"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Hazır ayar güncəllənmədi"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Hazır Ayar"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seçilib"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alətlər"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Canlı Altyazı"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Qeyd"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Aşağı prioritet bildiriş işarələrini göstərin"</string>
     <string name="other" msgid="429768510980739978">"Digər"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"lövhəni silin"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"sona lövhə əlavə edin"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Lövhəni köçürün"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Lövhə əlavə edin"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyinə köçürün"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyinə əlavə edin"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Mövqe yanlışdır."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"istifadəçi seçin"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"İnternet yoxdur"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ayarlarını açın."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Ayarların sıralanmasını redaktə edin."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Qidalanma düyməsi menyusu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> səhifədən <xliff:g id="ID_1">%1$d</xliff:g> səhifə"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekran kilidi"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(bağlantı kəsildi)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Dəyişmək olmur. Yenidən cəhd etmək üçün toxunun."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Cihaz qoşun"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu sessiyanı yayımlamaq üçün tətbiqi açın."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Naməlum tətbiq"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Yayımı dayandırın"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Audio çıxış üçün əlçatan cihazlar."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Əsas səhifəyə keçin"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Son tətbiqlərə baxın"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Hazırdır"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Yenidən cəhd edin!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Geri qayıdın"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Taçpeddə üç barmaqla sola və ya sağa sürüşdürün"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Əla!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Geri getmə jestini tamamladınız."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Taçpedi istifadə edərək geri qayıtmaq üçün üç barmağınızla sola və ya sağa çəkin"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Əsas səhifəyə keçin"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Taçpeddə üç barmaqla yuxarı sürüşdürün"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Əla!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Əsas səhifəyə keçid jestini tamamladınız"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Ana ekrana keçmək üçün taçpeddə üç barmağınızla yuxarı çəkin"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Son tətbiqlərə baxın"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Taçpeddə üç barmaqla yuxarı çəkib saxlayın"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Əla!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Son tətbiqlərə baxmaq jestini tamamladınız."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Ən son tətbiqlərə baxmaq üçün taçpeddə üç barmağınızla yuxarı çəkin və saxlayın"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Bütün tətbiqlərə baxın"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Klaviaturada fəaliyyət açarına basın"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Əla!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"\"Bütün tətbiqlərə baxın\" jestini tamamladınız"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Bütün tətbiqlərinizə baxmaq üçün klaviaturada fəaliyyət düyməsini basın"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Öyrədici animasiya, oxudulmanı durdurmaq və davam etdirmək üçün klikləyin."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatura işığı"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Səviyyə %1$d/%2$d"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 6810018..d0c3fa3 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obaveštenje o sesiji snimanja ekrana je aktivno"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Želite da snimite ekran?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snimi jednu aplikaciju"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snimi ceo ekran"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Snimite ceo ekran: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kada snimate ceo ekran, snima se sve što je na njemu. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, audio i video sadržaj."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kada snimate aplikaciju, snima se sav sadržaj koji se prikazuje ili pušta u njoj. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, audio i video sadržaj."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snimi ekran"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadatih podešavanja nije uspelo"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Unapred određena podešavanja"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Izabrano"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alatke"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Titl uživo"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Beleška"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Prikaži ikone obaveštenja niskog prioriteta"</string>
     <string name="other" msgid="429768510980739978">"Drugo"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"uklonili pločicu"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"dodali pločicu na kraj"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Premestite pločicu"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Dodajte pločicu"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Premestite na <xliff:g id="POSITION">%1$d</xliff:g>. poziciju"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodajte na <xliff:g id="POSITION">%1$d</xliff:g>. poziciju"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozicija je nevažeća."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"odabrali korisnika"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nema interneta"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otvori podešavanja za <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Izmeni redosled podešavanja."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meni dugmeta za uključivanje"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. strana od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključan ekran"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(veza je prekinuta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Prebacivanje nije uspelo. Probajte ponovo."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Povežite uređaj"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste prebacivali ovu sesiju, otvorite aplikaciju."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi prebacivanje"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostupni uređaji za audio izlaz."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Idi na početni ekran"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Prikaži nedavno korišćene aplikacije"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gotovo"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Probajte ponovo."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazad"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Prevucite ulevo ili udesno sa tri prsta na tačpedu"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Super!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Dovršili ste pokret za povratak."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Da biste se vratili pomoću tačpeda, prevucite ulevo ili udesno sa tri prsta"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Idi na početni ekran"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Prevucite nagore sa tri prsta na tačpedu"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Odlično!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Dovršili ste pokret za povratak na početnu stranicu."</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Da biste otišli na početni ekran, prevucite nagore sa tri prsta na tačpedu"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Prikaži nedavno korišćene aplikacije"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Prevucite nagore i zadržite sa tri prsta na tačpedu"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Odlično!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Dovršili ste pokret za prikazivanje nedavno korišćenih aplikacija."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Da biste pregledali nedavne aplikacije, prevucite nagore i zadržite sa tri prsta na tačpedu"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Prikaži sve aplikacije"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite taster radnji na tastaturi"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Odlično!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Dovršili ste pokret za prikazivanje svih aplikacija."</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Pritisnite taster radnji na tastaturi da biste pregledali sve aplikacije"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animacija vodiča, kliknite da biste pauzirali i nastavili reprodukciju."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvetljenje tastature"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index d95fd67..b40801d 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Бягучае апавяшчэнне для сеанса запісу экрана"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Запісаць экран?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Запісаць адну праграму"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Запісаць змесціва ўсяго экрана"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Запісваць экран цалкам: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Пры запісе ўсяго экрана запісваецца ўсё, што паказваецца на экране. Таму прадухіліце паказ пароляў, плацежных рэквізітаў, паведамленняў, фота, відэа і аўдыя."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Пры запісе праграмы запісваецца ўсё, што паказваецца або прайграецца ў гэтай праграме. Таму прадухіліце паказ пароляў, плацежных рэквізітаў, паведамленняў, фота, відэа і аўдыя."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Запісаць экран"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не ўдалося абнавіць набор налад"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набор налад"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Выбрана"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Інструменты"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Аўтаматычныя субцітры"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Нататка"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Паказваць значкі апавяшчэнняў з нізкім прыярытэтам"</string>
     <string name="other" msgid="429768510980739978">"Іншае"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"выдаліць плітку"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"дадаць плітку ў канец"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Перамясціць плітку"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Дадаць плітку"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Перамясціць на пазіцыю <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Дадаць на пазіцыю <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Няправільнае месца."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"выбраць карыстальніка"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Няма падключэння да інтэрнэту"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Адкрыць налады <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Змяніць парадак налад."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню кнопкі сілкавання"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Старонка <xliff:g id="ID_1">%1$d</xliff:g> з <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Экран блакіроўкі"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(адключана)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не ўдалося пераключыцца. Дакраніцеся, каб паўтарыць спробу."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Падключыць прыладу"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Для трансляцыі гэтага сеанса адкрыйце праграму."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Невядомая праграма"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Спыніць трансляцыю"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Даступныя прылады для вываду аўдыя."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"На галоўную старонку"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Прагляд нядаўніх праграм"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Гатова"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Паспрабуйце яшчэ раз!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Правядзіце па сэнсарнай панэлі трыма пальцамі ўлева ці ўправа"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Выдатна!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Вы навучыліся рабіць жэст вяртання."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Каб вярнуцца назад з дапамогай сэнсарнай панэлі, правядзіце трыма пальцамі ўлева ці ўправа"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"На галоўны экран"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Правядзіце па сэнсарнай панэлі трыма пальцамі ўверх"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Выдатная праца!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Вы навучыліся рабіць жэст для пераходу на галоўны экран"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Каб перайсці на галоўны экран, правядзіце трыма пальцамі ўверх па сэнсарным экране"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Прагляд нядаўніх праграм"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Правядзіце па сэнсарнай панэлі трыма пальцамі ўверх і затрымайце пальцы"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Выдатная праца!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Вы скончылі вывучэнне жэсту для прагляду нядаўніх праграм."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Каб праглядзець нядаўнія праграмы, правядзіце трыма пальцамі ўверх па сэнсарным экране і затрымайце пальцы"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Глядзець усе праграмы"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Націсніце клавішу дзеяння на клавіятуры"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Выдатна!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Вы навучыліся рабіць жэст для прагляду ўсіх праграм"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Каб праглядзець усе праграмы, націсніце на клавішу дзеяння на клавіятуры"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Анімацыя ў дапаможніку: націсніце, каб прыпыніць ці ўзнавіць прайграванне."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Падсветка клавіятуры"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Узровень %1$d з %2$d"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 344c011..83aa4e5 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущо известие за сесия за записване на екрана"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Да се записва ли екранът?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Записване на едно приложение"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Записване на целия екран"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Записване на целия екран: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Когато записвате целия си екран, се записва всичко, което се показва на него. Затова бъдете внимателни с неща като пароли, подробности за начини на плащане, съобщения, снимки, аудио и видео."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Когато записвате приложение, се записва всичко, което се показва или възпроизвежда в него. Затова бъдете внимателни с неща като пароли, подробности за начини на плащане, съобщения, снимки, аудио и видео."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Записване на екрана"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Предварително зададените настройки не бяха актуализирани"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Предварително зададено"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Избрано"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Инструменти"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Надписи на живо"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Бележка"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Показване на иконите за известията с нисък приоритет"</string>
     <string name="other" msgid="429768510980739978">"Друго"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"премахване на панел"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"добавяне на панел в края"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Преместване на панел"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Добавяне на панел"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Преместване към позиция <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Добавяне към позиция <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Невалидна позиция."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"изберете потребител"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Няма връзка с интернет"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Отваряне на настройките за <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Редактиране на подредбата на настройките."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню за включване/изключване"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Страница <xliff:g id="ID_1">%1$d</xliff:g> от <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Заключен екран"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(връзката е прекратена)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не може да се превключи. Докоснете за нов опит."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Свързване на устройство"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"За да предавате тази сесия, моля, отворете приложението."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Неизвестно приложение"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Спиране на предаването"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Налични устройства за аудиоизход."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Към началния екран"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Преглед на скорошните приложения"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Опитайте отново!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Плъзнете три пръста наляво или надясно по сензорния панел"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Чудесно!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Изпълнихте жеста за връщане назад."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"За да се върнете назад чрез сензорния панел, прекарайте три пръста наляво или надясно"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Към началния екран"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Плъзнете три пръста нагоре по сензорния панел"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Отлично!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Изпълнихте жеста за преминаване към началния екран"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Плъзнете три пръста нагоре по сензорния панел, за да преминете към началния екран"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Преглед на скорошните приложения"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Плъзнете три пръста нагоре по сензорния панел и задръжте"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Отлично!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Изпълнихте жеста за преглед на скорошните приложения."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"За да прегледате скорошните приложения, плъзнете три пръста нагоре по сензорния панел и задръжте"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Преглед на всички приложения"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Натиснете клавиша за действия на клавиатурата си"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Браво!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Изпълнихте жеста за преглед на всички приложения"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Натиснете клавиша за действия на клавиатурата си, за да прегледате всичките си приложения"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Анимация за урока. Кликнете, за да поставите на пауза и да възобновите възпроизвеждането."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Подсветка на клавиатурата"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Ниво %1$d от %2$d"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index d7b24c8..b927ad1 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রিন রেকর্ডিং সেশন চলার বিজ্ঞপ্তি"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"আপনার স্ক্রিন রেকর্ড করবেন?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"একটি অ্যাপ রেকর্ড করুন"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"সম্পূর্ণ স্ক্রিন রেকর্ড করুন"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"পুরো স্ক্রিন রেকর্ড করুন: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"আপনার সম্পূর্ণ স্ক্রিন রেকর্ড করার সময়, আপনার স্ক্রিনে দেখানো সব কিছু রেকর্ড করা হয়। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ের ক্ষেত্রে সতর্ক থাকুন।"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"আপনি কোনও অ্যাপ রেকর্ড করার সময়, সেই অ্যাপে দেখানো বা চালানো সব কিছু রেকর্ড করা হয়। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ের ক্ষেত্রে সতর্ক থাকুন।"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"স্ক্রিন রেকর্ড করুন"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"প্রিসেট আপডেট করা যায়নি"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"প্রিসেট"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"বেছে নেওয়া হয়েছে"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"টুল"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"লাইভ ক্যাপশন"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"মনে রাখবেন"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"কম-গুরুত্বপূর্ণ বিজ্ঞপ্তির আইকন দেখুন"</string>
     <string name="other" msgid="429768510980739978">"অন্যান্য"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"টাইল সরান"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"শেষে টাইল যোগ করুন"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"টাইল সরান"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"টাইল যোগ করুন"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g>-এ সরান"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"অবস্থান <xliff:g id="POSITION">%1$d</xliff:g>-এ যোগ করুন"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"পজিশন সঠিক নয়।"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ব্যবহারকারী বেছে নিন"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ইন্টারনেট কানেকশন নেই"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> সেটিংস খুলুন৷"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ক্রম বা সেটিংস সম্পাদনা করুন৷"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"পাওয়ার মেনু"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>টির মধ্যে <xliff:g id="ID_1">%1$d</xliff:g> নং পৃষ্ঠা"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"লক স্ক্রিন"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ডিসকানেক্ট হয়ে গেছে)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"পাল্টানো যাচ্ছে না। আবার চেষ্টা করতে ট্যাপ করুন।"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"ডিভাইস কানেক্ট করুন"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"এই সেশন কাস্ট করার জন্য, অ্যাপ খুলুন।"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"অজানা অ্যাপ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"কাস্ট করা বন্ধ করুন"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"অডিও আউটপুটের জন্য উপলভ্য ডিভাইস।"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"হোমে যান"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"সম্প্রতি ব্যবহার করা হয়েছে এমন অ্যাপ দেখুন"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"হয়ে গেছে"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"আবার চেষ্টা করুন!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ফিরে যান"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"আপনার টাচপ্যাডে তিনটি আঙুল ব্যবহার করে বাঁদিকে বা ডানদিকে সোয়াইপ করুন"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"সাবাস!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"জেসচার ব্যবহার করে কীভাবে ফিরে যাওয়া যায় সেই সম্পর্কে আপনি জেনেছেন।"</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"নিজের টাচপ্যাড ব্যবহার করে ফিরে যেতে, তিনটি আঙুল ব্যবহার করে বাঁদিকে বা ডানদিকে সোয়াইপ করুন"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"হোমে যান"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"আপনার টাচপ্যাডে তিনটি আঙুলের সাহায্যে উপরের দিকে সোয়াইপ করুন"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"অসাধারণ!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"জেসচার ব্যবহার করে কীভাবে হোমে ফিরে যাওয়া যায় সেই সম্পর্কে আপনি জেনেছেন"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"আপনার হোম স্ক্রিনে যেতে নিজের টাচপ্যাডে তিনটি আঙুল ব্যবহার করে উপরের দিকে সোয়াইপ করুন"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"সম্প্রতি ব্যবহার করা হয়েছে এমন অ্যাপ দেখুন"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"আপনার টাচপ্যাডে তিনটি আঙুল ব্যবহার করে উপরের দিকে সোয়াইপ করে ধরে রাখুন"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"অসাধারণ!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"সম্প্রতি ব্যবহার করা হয়েছে এমন অ্যাপের জেসচার দেখা সম্পূর্ণ করেছেন।"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"সাম্প্রতিক অ্যাপ দেখতে, নিজের টাচপ্যাডে তিনটি আঙুল ব্যবহার করে উপরের দিকে সোয়াইপ করে হোল্ড করুন"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"সব অ্যাপ দেখুন"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"আপনার কীবোর্ডে অ্যাকশন কী প্রেস করুন"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"দারুণ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"আপনি \'সব অ্যাপের জেসচার দেখুন\' টিউটোরিয়াল সম্পূর্ণ করেছেন"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"নিজের সব অ্যাপ দেখতে আপনার কীবোর্ডে অ্যাকশন \'কী\' প্রেস করুন"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"টিউটোরিয়াল অ্যানিমেশন পজ করুন এবং আবার চালু করতে ক্লিক করুন।"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"কীবোর্ড ব্যাকলাইট"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-এর মধ্যে %1$d লেভেল"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index b858459..defc62e 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obavještenje za sesiju snimanja ekrana je u toku"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Snimati ekran?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snimaj jednu aplikaciju"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snimaj cijeli ekran"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Snimi cijeli ekran: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kada snimate cijeli ekran, snimat će se sve što se prikazuje na ekranu. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kada snimate aplikaciju, snimat će se sve što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snimaj ekran"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadane postavke nije uspjelo"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Zadana postavka"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Odabrano"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alati"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatski titlovi"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Bilješka"</string>
@@ -960,9 +976,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Prikaži ikone obavještenja niskog prioriteta"</string>
     <string name="other" msgid="429768510980739978">"Ostalo"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"uklanjanje kartice"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"dodavanje kartice na kraj"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"dodavanje kartice na posljednji položaj"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Pomjeranje kartice"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Dodavanje kartice"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Dodajte karticu na željeni položaj"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Pomjeranje u položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodavanje u položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nevažeći položaj."</string>
@@ -978,7 +994,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"odaberete korisnika"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nema internetske veze"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otvori postavke za: <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Urediti raspored postavki."</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"Uredite redoslijed brzih postavki."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meni napajanja"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Stranica <xliff:g id="ID_1">%1$d</xliff:g> od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključani ekran"</string>
@@ -1209,7 +1225,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(veza je prekinuta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nije moguće prebaciti. Dodirnite da pokušate ponovo."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Povežite uređaj"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da emitirate ovu sesiju, otvorite aplikaciju."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi emitiranje"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostupni uređaji za audio izlaz."</string>
@@ -1468,32 +1483,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Odlazak na početni ekran"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Prikaži nedavne aplikacije"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gotovo"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Pokušajte ponovo!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazad"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Prevucite ulijevo ili udesno s tri prsta na dodirnoj podlozi"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Lijepo!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Savladali ste pokret za vraćanje."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Da se vratite pomoću dodirne podloge, prevucite ulijevo ili udesno s tri prsta"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Odlazak na početni ekran"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Prevucite nagore s tri prsta na dodirnoj podlozi"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Sjajno!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Savladali ste pokret za odlazak na početni ekran"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Prevucite nagore s tri prsta na dodirnoj podlozi da odete na početni ekran"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Prikaz nedavnih aplikacija"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Prevucite nagore i zadržite s tri prsta na dodirnoj podlozi"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Sjajno!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Izvršili ste pokret za prikaz nedavnih aplikacija."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Da pogledate nedavne aplikacije, prevucite nagore i zadržite s tri prsta na dodirnoj podlozi"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Pogledajte sve aplikacije"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite tipku radnji na tastaturi"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Odlično!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Izvršili ste pokret za prikaz svih aplikacija"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Pritisnite tipku radnji na tastaturi da pogledate sve aplikacije"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animacija vodiča; pauziranje i nastavak reprodukcije klikom."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tastature"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index c8f371c..05c9d81 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificació en curs d\'una sessió de gravació de la pantalla"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vols gravar la pantalla?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grava una aplicació"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grava tota la pantalla"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Grava tota la pantalla: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quan graves tota la pantalla, es grava tot el que es mostra en pantalla. Per aquest motiu, ves amb compte amb elements com les contrasenyes, les dades de pagament, els missatges, les fotos, i l\'àudio i el vídeo."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quan graves una aplicació, es grava tot el que es mostra o es reprodueix en aquesta aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos, i l\'àudio i el vídeo."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grava la pantalla"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"No s\'ha pogut actualitzar el valor predefinit"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Valors predefinits"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionat"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Eines"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítols instantanis"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Mostra les icones de notificació amb prioritat baixa"</string>
     <string name="other" msgid="429768510980739978">"Altres"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"suprimir el mosaic"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"afegir un mosaic al final"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mou el mosaic"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Afegeix una icona"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mou a la posició <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Afegeix a la posició <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"La posició no és vàlida."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"triar un usuari"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Sense connexió a Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Obre la configuració per a <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edita l\'ordre de la configuració."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú d\'engegada"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pàgina <xliff:g id="ID_1">%1$d</xliff:g> (<xliff:g id="ID_2">%2$d</xliff:g> en total)"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueig"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconnectat)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No es pot canviar. Torna-ho a provar."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connecta un dispositiu"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Per emetre aquesta sessió, obre l\'aplicació."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicació desconeguda"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Atura l\'emissió"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositius disponibles per a la sortida d\'àudio."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Ves a la pantalla d\'inici"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Mostra les aplicacions recents"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Fet"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Torna-ho a provar"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Torna"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Llisca cap a l\'esquerra o cap a la dreta amb tres dits al ratolí tàctil"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Molt bé!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Has completat el gest per tornar enrere."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Per tornar enrere amb el ratolí tàctil, llisca cap a l\'esquerra o cap a la dreta amb tres dits"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Ves a la pantalla d\'inici"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Llisca cap amunt amb tres dits al ratolí tàctil"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Ben fet!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Has completat el gest per anar a la pantalla d\'inici"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Llisca cap amunt amb tres dits al ratolí tàctil per anar a la pantalla d\'inici"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Mostra les aplicacions recents"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Llisca cap amunt amb tres dits i mantén-los premuts al ratolí tàctil"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Ben fet!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Has completat el gest per veure les aplicacions recents."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Per veure les aplicacions recents, llisca cap amunt amb tres dits i mantén-los premuts al ratolí tàctil"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Mostra totes les aplicacions"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Prem la tecla d\'acció al teclat"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Enhorabona!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Has completat el gest per veure totes les aplicacions"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Prem la tecla d\'acció al teclat per veure totes les aplicacions"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animació del tutorial; fes clic per posar en pausa i reprendre la reproducció."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroil·luminació del teclat"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivell %1$d de %2$d"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index efc699b..7ae4416 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Trvalé oznámení o relaci nahrávání"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Pořídit nahrávku obrazovky?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Nahrát jednu aplikaci"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Nahrát celou obrazovku"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Nahrát celou obrazovku: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Při nahrávání celé obrazovky se zaznamenává veškerý obsah na obrazovce. Buďte proto opatrní, když jde o hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Při nahrávání aplikace se zaznamenává všechno, co se v dané obrazovce zobrazuje nebo přehrává. Buďte proto opatrní, když jde o hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Nahrát obrazovku"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Předvolbu nelze aktualizovat"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Předvolba"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Vybráno"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nástroje"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Okamžité titulky"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Poznámka"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Zobrazit ikony oznámení s nízkou prioritou"</string>
     <string name="other" msgid="429768510980739978">"Jiné"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"odstranit dlaždici"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"přidat dlaždici na konec"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Přesunout dlaždici"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Přidat dlaždici"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Přesunout na pozici <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Přidat dlaždici na pozici <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozice není platná."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"zvolit uživatele"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nejste připojeni k internetu"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otevřít nastavení aplikace <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Upravit pořadí nastavení."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Nabídka vypínače"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Stránka <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Obrazovka uzamčení"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odpojeno)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nelze přepnout. Klepnutím opakujte akci."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Připojit zařízení"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pokud chcete odesílat relaci, otevřete aplikaci."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznámá aplikace"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zastavit odesílání"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostupná zařízení pro zvukový výstup."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Přejít na domovskou stránku"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Zobrazit nedávné aplikace"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Hotovo"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Zkuste to znovu."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Zpět"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Přejeďte po touchpadu třemi prsty doleva nebo doprava"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Skvělé!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Provedli jste gesto pro přechod zpět."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Pokud se chcete vrátit zpět pomocí touchpadu, přejeďte třemi prsty vlevo nebo vpravo"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Přejít na plochu"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Přejeďte po touchpadu třemi prsty nahoru"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Výborně!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Provedli jste gesto pro přechod na plochu"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Přejetím po touchpadu třemi prsty nahoru přejdete na plochu"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Zobrazit nedávné aplikace"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Přejeďte po touchpadu třemi prsty nahoru a podržte je"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Výborně!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Provedli jste gesto pro zobrazení nedávných aplikací."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Pokud chcete zobrazit poslední aplikace, přejeďte na touchpadu třemi prsty nahoru a podržte je"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Zobrazit všechny aplikace"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Stiskněte akční klávesu na klávesnici"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Výborně!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Provedli jste gesto k zobrazení všech aplikací"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Stisknutím akční klávesy na klávesnici zobrazíte všechny aplikace"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Výuková animace, kliknutím pozastavíte nebo obnovíte."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvícení klávesnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Úroveň %1$d z %2$d"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 4336a85..c168a30 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Konstant notifikation om skærmoptagelse"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vil du optage din skærm?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Optag én app"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Optag hele skærmen"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Optag hele skærmen: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Når du optager hele skærmen, bliver alt det, der vises på skærmen, optaget. Vær derfor forsigtig med ting såsom adgangskoder, betalingsoplysninger, beskeder, billeder, lyd og video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Når du optager en app, optages alt det, der vises eller afspilles i den pågældende app. Vær derfor forsigtig med ting såsom adgangskoder, betalingsoplysninger, beskeder, billeder, lyd og video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Optag skærm"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Forindstillingen kunne ikke opdateres"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forindstilling"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valgt"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Værktøjer"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Livetekstning"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Vis ikoner for notifikationer med lav prioritet"</string>
     <string name="other" msgid="429768510980739978">"Andet"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"fjern felt"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"føj feltet til slutningen"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Flyt felt"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Tilføj felt"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Flyt til <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Føj til lokation <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Positionen er ugyldig."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"vælge bruger"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Intet internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Åbn <xliff:g id="ID_1">%s</xliff:g>-indstillinger."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Rediger rækkefølgen af indstillinger."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu for afbryderknappen"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Side <xliff:g id="ID_1">%1$d</xliff:g> af <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Låseskærm"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(afbrudt)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Det var ikke muligt at skifte. Tryk for at prøve igen."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Tilknyt en enhed"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Åbn appen for at caste denne session."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ukendt app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop med at caste"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Enheder, der er tilgængelige for lydudgang."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Gå til startsiden"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Se seneste apps"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Udfør"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Prøv igen!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Gå tilbage"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Stryg til venstre eller højre med tre fingre på touchpladen"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Sådan!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Du har udført bevægelsen for Gå tilbage."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Du kan gå tilbage ved at stryge til venstre eller højre med tre fingre på touchpladen"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Gå til startskærmen"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Stryg opad med tre fingre på touchpladen"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Flot!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Du har udført bevægelsen for at gå til startsiden"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Stryg opad med tre fingre på touchpladen for at gå til din startskærm"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Se seneste apps"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Stryg opad, og hold tre fingre på touchpladen"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Godt klaret!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Du har udført bevægelsen for at se de seneste apps."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Du kan se nyligt brugte apps ved at stryge opad og holde tre fingre nede på touchpladen"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Se alle apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tryk på handlingstasten på dit tastatur"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Flot klaret!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Du har udført bevægelsen for at se alle apps"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Tryk på handlingstasten på dit tastatur for at se alle dine apps"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animation med vejledning. Klik for at sætte afspilningen på pause og genoptage den."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastaturets baggrundslys"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d af %2$d"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 6e8cffe..eaa849d 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Fortlaufende Benachrichtigung für eine Bildschirmaufzeichnung"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Bildschirm aufnehmen?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Einzelne App aufnehmen"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gesamten Bildschirm aufnehmen"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Gesamten Bildschirm aufnehmen: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Wenn du den gesamten Bildschirm aufnimmst, ist in der Aufnahme alles zu sehen, was auf dem Bildschirm angezeigt wird. Sei also vorsichtig mit Informationen wie Passwörtern, Zahlungsdetails, Nachrichten, Fotos sowie Audio- und Videoinhalten."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Wenn du eine App aufnimmst, ist in der Aufnahme alles zu sehen, was in dieser App angezeigt oder abgespielt wird. Sei also vorsichtig mit Informationen wie Passwörtern, Zahlungsdetails, Nachrichten, Fotos sowie Audio- und Videoinhalten."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Bildschirm aufnehmen"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Voreinstellung konnte nicht aktualisiert werden"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voreinstellung"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Ausgewählt"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatische Untertitel"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notiz"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Symbole für Benachrichtigungen mit einer niedrigen Priorität anzeigen"</string>
     <string name="other" msgid="429768510980739978">"Sonstiges"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"Entfernen der Kachel"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"Hinzufügen der Kachel am Ende"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Kachel verschieben"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Kachel hinzufügen"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Auf Position <xliff:g id="POSITION">%1$d</xliff:g> verschieben"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Zur Position <xliff:g id="POSITION">%1$d</xliff:g> hinzufügen"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position ist ungültig."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"Auswählen des Nutzers"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Kein Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Einstellungen für <xliff:g id="ID_1">%s</xliff:g> öffnen."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Reihenfolge der Einstellungen bearbeiten."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Ein-/Aus-Menü"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Seite <xliff:g id="ID_1">%1$d</xliff:g> von <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Sperrbildschirm"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nicht verbunden)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Wechseln nicht möglich. Tippe, um es noch einmal zu versuchen."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Gerät verbinden"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Öffne zum Streamen dieser Sitzung die App."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unbekannte App"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Streaming beenden"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Für die Audioausgabe verfügbare Geräte."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Zum Startbildschirm"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Letzte Apps aufrufen"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Fertig"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Noch einmal versuchen"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Zurück"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Wische mit drei Fingern auf dem Touchpad nach links oder rechts"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Sehr gut!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Du hast das Tutorial für die „Zurück“-Touch-Geste abgeschlossen."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Wenn du mit dem Touchpad zurückgehen möchtest, wische mit drei Fingern nach links oder rechts"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Startbildschirm"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Wische an einer beliebigen Stelle auf dem Touchpad mit drei Fingern nach oben"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Gut gemacht!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Du hast den Schritt für die „Startbildschirm“-Touch-Geste abgeschlossen"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Wenn du zum Startbildschirm gelangen möchtest, wische auf dem Touchpad mit drei Fingern nach oben"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Letzte Apps aufrufen"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Wische mit drei Fingern nach oben und halte das Touchpad gedrückt"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Gut gemacht!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Du hast das Tutorial für die Touch-Geste zum Aufrufen der zuletzt verwendeten Apps abgeschlossen."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Wenn du zuletzt verwendete Apps aufrufen möchtest, wische mit drei Fingern nach oben und halte das Touchpad gedrückt"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Alle Apps anzeigen"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Drücke die Aktionstaste auf deiner Tastatur"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Perfekt!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Du hast das Tutorial für die Touch-Geste zum Aufrufen aller Apps abgeschlossen"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Drücke die Aktionstaste auf deiner Tastatur, um alle deine Apps aufzurufen"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animation während des Tutorials, zum Pausieren und Fortsetzen der Wiedergabe klicken."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastaturbeleuchtung"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d von %2$d"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 2182220..dab393cf 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ειδοποίηση σε εξέλιξη για μια περίοδο λειτουργίας εγγραφής οθόνης"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Να γίνει εγγραφή της οθόνης σας;"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Εγγραφή μίας εφαρμογής"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Εγγραφή ολόκληρης της οθόνης"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Εγγραφή ολόκληρης της οθόνης: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Όταν κάνετε εγγραφή ολόκληρης της οθόνη σας, καταγράφεται οτιδήποτε εμφανίζεται σε αυτήν. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα, τις φωτογραφίες, τον ήχο και το βίντεο."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Όταν κάνετε εγγραφή μιας εφαρμογής, καταγράφεται οτιδήποτε εμφανίζεται ή αναπαράγεται στη συγκεκριμένη εφαρμογή. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα, τις φωτογραφίες, τον ήχο και το βίντεο."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Εγγραφή οθόνης"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Δεν ήταν δυνατή η ενημέρωση της προεπιλογής"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Προεπιλογή"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Έχει επιλεγεί"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Εργαλεία"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Ζωντανοί υπότιτλοι"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Σημείωση"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Εμφάνιση εικονιδίων ειδοποιήσεων χαμηλής προτεραιότητας"</string>
     <string name="other" msgid="429768510980739978">"Άλλο"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"κατάργηση πλακιδίου"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"προσθήκη πλακιδίου στο τέλος"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Μετακίνηση πλακιδίου"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Προσθήκη πλακιδίου"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Μετακίνηση στη θέση <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Προσθήκη στη θέση <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Μη έγκυρη θέση."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"επιλογή χρήστη"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Δεν υπάρχει σύνδεση στο διαδίκτυο"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Άνοιγμα ρυθμίσεων <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Επεξεργασία σειράς ρυθμίσεων."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Μενού λειτουργίας"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Σελίδα <xliff:g id="ID_1">%1$d</xliff:g> από <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Οθόνη κλειδώματος"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(αποσυνδέθηκε)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Δεν είναι δυνατή η εναλλαγή. Πατήστε για επανάληψη."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Σύνδεση συσκευής"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Για μετάδοση της περιόδου σύνδεσης, ανοίξτε την εφαρμογή."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Άγνωστη εφαρμογή"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Διακοπή μετάδοσης"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Διαθέσιμες συσκευές για έξοδο ήχου."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Αρχική"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Προβολή πρόσφατων εφαρμογών"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Τέλος"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Δοκιμάστε ξανά!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Επιστροφή"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Σύρετε προς τα αριστερά ή τα δεξιά με τρία δάχτυλα στην επιφάνεια αφής"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Ωραία!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Ολοκληρώσατε την κίνηση επιστροφής."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Για επιστροφή με χρήση της επιφάνειας αφής, σύρετε προς τα αριστερά ή προς τα δεξιά με τρία δάχτυλα"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Αρχική"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Σύρετε προς τα επάνω με τρία δάχτυλα στην επιφάνεια αφής"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Μπράβο!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Ολοκληρώσατε την κίνηση μετάβασης στην αρχική οθόνη"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Για μετάβαση στην αρχική οθόνη, σύρετε προς τα επάνω με τρία δάχτυλα στην επιφάνεια αφής"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Προβολή πρόσφατων εφαρμογών"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Σύρετε προς τα επάνω με τρία δάχτυλα στην επιφάνεια αφής και μην τα σηκώσετε"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Μπράβο!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Ολοκληρώσατε την κίνηση για την προβολή πρόσφατων εφαρμογών."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Για προβολή πρόσφατων εφαρμογών, σύρετε προς τα επάνω με τρία δάχτυλα και κρατήστε τα δάχτυλά σας στην επιφάνεια αφής"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Προβολή όλων των εφαρμογών"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Πατήστε το πλήκτρο ενέργειας στο πληκτρολόγιό σας"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Μπράβο!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Ολοκληρώσατε την κίνηση για την προβολή όλων των εφαρμογών"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Πατήστε το πλήκτρο ενέργειας στο πληκτρολόγιο, για να δείτε όλες τις εφαρμογές σας"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Κινούμενη εικόνα οδηγού, κάντε κλικ για παύση και συνέχιση της αναπαραγωγής."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Οπίσθιος φωτισμός πληκτρολογίου"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Επίπεδο %1$d από %2$d"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 779e3f6..efab948 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Record your screen?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
@@ -960,9 +976,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string>
     <string name="other" msgid="429768510980739978">"Other"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"remove tile"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"add tile to end"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"add tile to the last position"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Move tile"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Add tile"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Add tile to desired position"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Move to <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Add to position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position invalid."</string>
@@ -978,7 +994,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"choose user"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"No Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edit order of settings."</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"Edit order of Quick Settings."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
@@ -1209,7 +1225,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connect a device"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Available devices for audio output."</string>
@@ -1468,32 +1483,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Go home"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"View recent apps"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Done"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Try again."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Swipe left or right using three fingers on your touchpad"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Nice!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"You completed the go back gesture."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"To go back using your touchpad, swipe left or right using three fingers"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Go home"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Swipe up with three fingers on your touchpad"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Well done!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"You completed the go home gesture"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Swipe up with three fingers on your touchpad to go to your home screen"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"View recent apps"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Swipe up and hold using three fingers on your touchpad"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Well done!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"You completed the view recent apps gesture."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"To view recent apps, swipe up and hold using three fingers on your touchpad"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"View all apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"You completed the view all apps gesture"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Press the action key on your keyboard to view all of your apps"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Tutorial animation, click to pause and resume play."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 22916c3..8486688 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -111,8 +111,8 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Record your screen?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
+    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="4882406311415082016">"Record this screen"</string>
+    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="4169494703993148253">"Record %s"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you’re recording your entire screen, anything shown on your screen is recorded. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you’re recording an app, anything shown or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
@@ -415,6 +415,13 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
+    <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
+    <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
+    <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Right"</string>
+    <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Expand to left and right separated controls"</string>
+    <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Collapse to unified control"</string>
+    <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Mute surroundings"</string>
+    <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Unmute surroundings"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
@@ -960,9 +967,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string>
     <string name="other" msgid="429768510980739978">"Other"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"remove tile"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"add tile to end"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"add tile to the last position"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Move tile"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Add tile"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Add tile to desired position"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Move to <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Add to position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position invalid."</string>
@@ -978,7 +985,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"choose user"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"No internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edit order of settings."</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"Edit order of Quick Settings."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
@@ -1209,7 +1216,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connect a device"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Available devices for audio output."</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 779e3f6..efab948 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Record your screen?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
@@ -960,9 +976,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string>
     <string name="other" msgid="429768510980739978">"Other"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"remove tile"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"add tile to end"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"add tile to the last position"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Move tile"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Add tile"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Add tile to desired position"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Move to <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Add to position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position invalid."</string>
@@ -978,7 +994,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"choose user"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"No Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edit order of settings."</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"Edit order of Quick Settings."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
@@ -1209,7 +1225,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connect a device"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Available devices for audio output."</string>
@@ -1468,32 +1483,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Go home"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"View recent apps"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Done"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Try again."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Swipe left or right using three fingers on your touchpad"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Nice!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"You completed the go back gesture."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"To go back using your touchpad, swipe left or right using three fingers"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Go home"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Swipe up with three fingers on your touchpad"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Well done!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"You completed the go home gesture"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Swipe up with three fingers on your touchpad to go to your home screen"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"View recent apps"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Swipe up and hold using three fingers on your touchpad"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Well done!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"You completed the view recent apps gesture."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"To view recent apps, swipe up and hold using three fingers on your touchpad"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"View all apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"You completed the view all apps gesture"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Press the action key on your keyboard to view all of your apps"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Tutorial animation, click to pause and resume play."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 779e3f6..efab948 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Record your screen?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Record entire screen: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
@@ -960,9 +976,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string>
     <string name="other" msgid="429768510980739978">"Other"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"remove tile"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"add tile to end"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"add tile to the last position"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Move tile"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Add tile"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Add tile to desired position"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Move to <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Add to position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position invalid."</string>
@@ -978,7 +994,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"choose user"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"No Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edit order of settings."</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"Edit order of Quick Settings."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
@@ -1209,7 +1225,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnected)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Can\'t switch. Tap to try again."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connect a device"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Available devices for audio output."</string>
@@ -1468,32 +1483,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Go home"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"View recent apps"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Done"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Try again."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Swipe left or right using three fingers on your touchpad"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Nice!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"You completed the go back gesture."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"To go back using your touchpad, swipe left or right using three fingers"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Go home"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Swipe up with three fingers on your touchpad"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Well done!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"You completed the go home gesture"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Swipe up with three fingers on your touchpad to go to your home screen"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"View recent apps"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Swipe up and hold using three fingers on your touchpad"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Well done!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"You completed the view recent apps gesture."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"To view recent apps, swipe up and hold using three fingers on your touchpad"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"View all apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Press the action key on your keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Well done!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"You completed the view all apps gesture"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Press the action key on your keyboard to view all of your apps"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Tutorial animation, click to pause and resume play."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 1f3aee8..e9786e3 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación constante para una sesión de grabación de pantalla"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"¿Quieres grabar la pantalla?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grabar una app"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grabar toda la pantalla"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Grabar toda la pantalla: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Cuando grabes toda la pantalla, se grabará todo lo que se muestre en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cuando grabes una app, se grabará todo lo que se muestre o reproduzca en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabar pantalla"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"No se pudo actualizar el ajuste predeterminado"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Ajuste predeterminado"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionado"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Herramientas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitulado instantáneo"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar íconos de notificaciones con prioridad baja"</string>
     <string name="other" msgid="429768510980739978">"Otros"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"quitar tarjeta"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"agregar tarjeta al final"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mover la tarjeta"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Agregar tarjeta"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mover a <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Agregar a la posición <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posición no válida"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"elegir usuario"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Sin Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Abrir configuración de <xliff:g id="ID_1">%s</xliff:g>"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editar orden de configuración"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú de encendido"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueo"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No se pudo conectar. Presiona para volver a intentarlo."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Conectar un dispositivo"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para transmitir esta sesión, abre la app"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconocida"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Detener transmisión"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos disponibles para salida de audio."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Ir a la página principal"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Ver apps recientes"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Listo"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Vuelve a intentarlo"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Atrás"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Desliza hacia la izquierda o la derecha con tres dedos en el panel táctil"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"¡Muy bien!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Completaste el gesto para ir atrás."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Para volver con el panel táctil, desliza tres dedos hacia la izquierda o la derecha"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Ir a la página principal"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Desliza hacia arriba con tres dedos en el panel táctil"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"¡Bien hecho!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Completaste el gesto para ir a la página principal"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Desliza tres dedos hacia arriba en el panel táctil para ir a la pantalla principal"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Ver apps recientes"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Desliza hacia arriba con tres dedos en el panel táctil y mantenlos presionados"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"¡Bien hecho!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Completaste el gesto para ver las apps recientes."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Para ver las apps recientes, desliza tres dedos hacia arriba y mantenlos presionados en el panel táctil"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todas las apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Presiona la tecla de acción en el teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"¡Bien hecho!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Completaste el gesto para ver todas las apps"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Presiona la tecla de acción en el teclado para ver todas las apps"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animación del instructivo. Haz clic para pausar y reanudar la reproducción."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación del teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 8ae684a..9460874 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación continua de una sesión de grabación de la pantalla"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"¿Grabar la pantalla?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grabar una aplicación"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grabar toda la pantalla"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Grabar toda la pantalla: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Cuando grabas toda la pantalla, se graba todo lo que se muestre en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cuando grabas una aplicación, se graba todo lo que se muestre o reproduzca en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabar pantalla"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"No se ha podido actualizar el preajuste"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preajuste"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionado"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Herramientas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítulos automáticos"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar iconos de notificaciones con prioridad baja"</string>
     <string name="other" msgid="429768510980739978">"Otros"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"quitar recuadro"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"añadir recuadro al final"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mover recuadro"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Añadir recuadro"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mover a <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Añadir a la posición <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posición no válida."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"elegir un usuario"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Sin Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Abrir ajustes de <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Cambiar el orden de los ajustes."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú de encendido"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueo"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"No se puede cambiar. Toca para volver a intentarlo."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Conectar un dispositivo"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para enviar esta sesión, abre la aplicación."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicación desconocida"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Dejar de enviar contenido"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos disponibles para la salida de audio."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Ir a Inicio"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Ver aplicaciones recientes"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Hecho"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Vuelve a intentarlo."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Atrás"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Desliza hacia la izquierda o la derecha con tres dedos en el panel táctil"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"¡Genial!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Has completado el gesto para volver."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Para volver atrás usando el panel táctil, desliza tres dedos hacia la izquierda o la derecha"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Ir a Inicio"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Desliza hacia arriba con tres dedos en el panel táctil"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"¡Bien hecho!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Has completado el gesto para ir a la pantalla de inicio"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Desliza tres dedos hacia arriba en el panel táctil para ir a la pantalla de inicio"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Ver aplicaciones recientes"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Desliza hacia arriba con tres dedos y mantén pulsado en el panel táctil"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"¡Bien hecho!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Has completado el gesto para ver las aplicaciones recientes."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Para ver las aplicaciones recientes, desliza tres dedos hacia arriba y mantén pulsado en el panel táctil"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todas las aplicaciones"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pulsa la tecla de acción de tu teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"¡Muy bien!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Has completado el gesto para ver todas las aplicaciones"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Pulsa la tecla de acción de tu teclado para ver todas tus aplicaciones"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animación del tutorial, haz clic para pausar y reanudar la reproducción."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación del teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index e3e7263..3999042 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pooleli märguanne ekraanikuva salvestamise seansi puhul"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Kas salvestada ekraanikuvast video?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Ühe rakenduse salvestamine"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Kogu ekraanikuva salvestamine"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Kogu ekraanikuva salvestamine: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kui salvestate kogu ekraani, salvestatakse kõik ekraanil kuvatud andmed. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kui salvestate rakendust, salvestatakse kõik, mida selles rakenduses näidatakse või esitatakse. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Salvesta ekraanikuva"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Eelseadistust ei saanud värskendada"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Eelseadistus"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valitud"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tööriistad"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Reaalajas subtiitrid"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Märkus"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Kuva madala prioriteediga märguande ikoonid"</string>
     <string name="other" msgid="429768510980739978">"Muu"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"paani eemaldamiseks"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"paani lõppu lisamiseks"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Teisalda paan"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Lisa paan"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Teisaldamine asendisse <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Lisamine asendisse <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Sobimatu asukoht."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"valige kasutaja"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Interneti-ühendus puudub"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Ava teenuse <xliff:g id="ID_1">%s</xliff:g> seaded."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Muuda seadete järjestust."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Toitemenüü"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Leht <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lukustuskuva"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ühendus on katkestatud)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ei saa lülitada. Puudutage uuesti proovimiseks."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Seadme ühendamine"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Selle seansi ülekandmiseks avage rakendus."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Tundmatu rakendus"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Lõpeta ülekanne"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Saadaolevad seadmed heli esitamiseks."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Avakuvale"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Hiljutiste rakenduste vaatamine"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Valmis"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Proovige uuesti!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Tagasi"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Pühkige puuteplaadil kolme sõrmega vasakule või paremale"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Tubli töö!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Tegite tagasiliikumise liigutuse."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Puuteplaadi abil tagasi liikumiseks pühkige kolme sõrmega vasakule või paremale"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Avakuvale"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Pühkige puuteplaadil kolme sõrmega üles"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Väga hea!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Tegite avakuvale minemise liigutuse"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Avakuvale liikumiseks pühkige puuteplaadil kolme sõrmega üles"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Hiljutiste rakenduste vaatamine"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Pühkige üles ja hoidke kolme sõrme puuteplaadil"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Väga hea!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Tegite hiljutiste rakenduste vaatamise liigutuse."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Hiljutiste rakenduste kuvamiseks pühkige puuteplaadil kolme sõrmega üles ja hoidke sõrmi puuteplaadil"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Kõigi rakenduste kuvamine"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Vajutage klaviatuuril toiminguklahvi"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Hästi tehtud!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Tegite kõigi rakenduste vaatamise liigutuse"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Kõigi oma rakenduste kuvamiseks vajutage klaviatuuril toiminguklahvi"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Õpetlik animatsioon, klõpsake esitamise peatamiseks ja jätkamiseks."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatuuri taustavalgustus"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Tase %1$d/%2$d"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index e284597..88a46c1 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pantailaren grabaketa-saioaren jakinarazpen jarraitua"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Pantaila grabatu nahi duzu?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grabatu aplikazio bat"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grabatu pantaila osoa"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Grabatu pantaila osoa: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Pantaila osoa grabatzen ari zarenean, pantailan agertzen den guztia grabatzen da. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Aplikazio bat grabatzen ari zarenean, aplikazio horretan agertzen den edo bertan erreproduzitzen ari den guztia grabatzen da. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabatu pantaila"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ezin izan da eguneratu aurrezarpena"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Aurrezarpena"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Hautatuta"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tresnak"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Istanteko azpitituluak"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Oharra"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Erakutsi lehentasun txikiko jakinarazpenen ikonoak"</string>
     <string name="other" msgid="429768510980739978">"Beste bat"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"kendu lauza"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"gehitu lauza amaieran"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mugitu lauza"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Gehitu lauza"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Eraman <xliff:g id="POSITION">%1$d</xliff:g>garren lekura"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Gehitu <xliff:g id="POSITION">%1$d</xliff:g>garren lekuan"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Kokapenak ez du balio."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"erabiltzailea aukeratzeko"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Ez dago Interneteko konexiorik"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Ireki <xliff:g id="ID_1">%s</xliff:g> ezarpenak."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editatu ezarpenen ordena."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Itzaltzeko menua"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g> orria"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantaila blokeatua"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(deskonektatuta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ezin da aldatu. Berriro saiatzeko, sakatu hau."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Konektatu gailu bat"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Saioa ireki nahi baduzu, ireki aplikazioa."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikazio ezezaguna"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Gelditu igorpena"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Audio-irteerarako gailu erabilgarriak."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Joan orri nagusira"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Ikusi azkenaldiko aplikazioak"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Eginda"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Saiatu berriro!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Egin atzera"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Pasatu 3 hatz ezkerrera edo eskuinera ukipen-panelean"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Ederki!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Ikasi duzu atzera egiteko keinua."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Ukipen-panelaren bidez atzera egiteko, pasatu 3 hatz ezkerrera edo eskuinera"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Joan orri nagusira"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Pasatu 3 hatz gora ukipen-panelean"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Bikain!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Ikasi duzu orri nagusira joateko keinua"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Orri nagusira joateko, pasatu 3 hatz gora ukipen-panelean"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Ikusi azkenaldiko aplikazioak"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Pasatu 3 hatz gora eta eduki sakatuta ukipen-panelean"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Bikain!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Osatu duzu azkenaldiko aplikazioak ikusteko keinua."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Azkenaldiko aplikazioak ikusteko, pasatu 3 hatz gora eta eduki sakatuta ukipen-panelean"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ikusi aplikazio guztiak"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Sakatu teklatuko ekintza-tekla"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bikain!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Osatu duzu aplikazio guztiak ikusteko keinua"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Sakatu teklatuko ekintza-tekla aplikazio guztiak ikusteko"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Tutorialeko animazioa. Sakatu pausatzeko eta erreproduzitzeari berrekiteko."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Teklatuaren hondoko argia"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d/%2$d maila"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 0abbd26..5e851dc 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"اعلان درحال انجام برای جلسه ضبط صفحه‌نمایش"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"صفحه‌نمایش ضبط شود؟"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ضبط یک برنامه"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ضبط کل صفحه‌نمایش"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"‏ضبط کردن کل صفحه‌نمایش: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"وقتی کل صفحه‌نمایش را ضبط می‌کنید، هر چیزی که در صفحه‌نمایش نشان داده شود ضبط خواهد شد. درنتیجه مراقب چیزهایی مثل گذرواژه‌ها، جزئیات پرداخت، پیام‌ها، عکس‌ها، و صدا و تصویر باشید."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"وقتی برنامه‌ای را ضبط می‌کنید، هر چیزی که در آن برنامه نشان داده شود یا پخش شود ضبط خواهد شد. درنتیجه مراقب چیزهایی مثل گذرواژه‌ها، جزئیات پرداخت، پیام‌ها، عکس‌ها، و صدا و تصویر باشید."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ضبط صفحه‌نمایش"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"پیش‌تنظیم به‌روزرسانی نشد"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"پیش‌تنظیم"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"انتخاب‌شده"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ابزارها"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"زیرنویس زنده ناشنوایان"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"یادداشت"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"نمایش نمادهای اعلان کم‌اهمیت"</string>
     <string name="other" msgid="429768510980739978">"موارد دیگر"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"برداشتن کاشی"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"افزودن کاشی به انتها"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"انتقال کاشی"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"افزودن کاشی"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"انتقال به <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"افزودن به موقعیت <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"موقعیت نامعتبر است."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"انتخاب کاربر"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"عدم اتصال به اینترنت"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"باز کردن تنظیمات <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ویرایش ترتیب تنظیمات."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"منوی روشن/خاموش"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"صفحه <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"صفحه قفل"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(اتصال قطع شد)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"عوض نمی‌شود. برای تلاش مجدد تک‌ضرب بزنید."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"متصل کردن دستگاه"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"برای ارسال محتوای این جلسه، لطفاً برنامه را باز کنید."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"برنامه ناشناس"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"توقف پخش محتوا"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"دستگاه‌های دردسترس برای خروجی صوتی."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"رفتن به صفحه اصلی"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"مشاهده برنامه‌های اخیر"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"تمام"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"دوباره امتحان کنید!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"برگشتن"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"با سه انگشت روی صفحه لمسی تند به چپ یا راست بکشید."</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"چه خوب!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"اشاره برگشت را تکمیل کردید."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"برای برگشتن بااستفاده از صفحه لمسی، با سه انگشت تند به‌چپ یا راست بکشید"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"رفتن به صفحه اصلی"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"با سه انگشت روی صفحه لمسی تند به بالا بکشید"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"عالی است!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"اشاره رفتن به صفحه اصلی را تکمیل کردید"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"برای رفتن به صفحه اصلی، با سه انگشت تند به‌بالا بکشید"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"مشاهده برنامه‌های اخیر"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"با سه انگشت روی صفحه لمسی تند به بالا بکشید و نگه دارید"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"عالی است!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"اشاره «مشاهده برنامه‌های اخیر» را تمام کردید"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"برای مشاهده برنامه‌های اخیر، با سه انگشت روی صفحه لمسی تند به‌بالا بکشید و نگه دارید"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"مشاهده همه برنامه‌ها"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"دکمه کنش را روی صفحه لمسی فشار دهید"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"عالی بود!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"اشاره «مشاهده همه برنامه‌ها» را تمام کردید"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"برای مشاهده همه برنامه‌ها، دکمه کنش را روی صفحه‌کلید فشار دهید"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"پویانمایی آموزش گام‌به‌گام، برای توقف موقت و ازسرگیری پخش کلیک کنید."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"نور پس‌زمینه صفحه‌کلید"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏سطح %1$d از %2$d"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 03d1441..b257a89 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pysyvä ilmoitus näytön tallentamisesta"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Tallennetaanko näytön toimintaa?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Tallenna yhdestä sovelluksesta"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Tallenna koko näyttö"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Tallenna koko näyttö: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kun tallennat koko näyttöä, kaikki näytöllä näkyvä sisältö tallennetaan. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä, kuvia, audiota tai videoita."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kun tallennat sovellusta, kaikki sovelluksessa näkyvä tai toistettu sisältö tallennetaan. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä, kuvia, audiota tai videoita."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Tallenna näyttö"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Esiasetusta ei voitu muuttaa"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Esiasetus"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valittu"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Työkalut"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Livetekstitys"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Muistiinpano"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Näytä vähemmän tärkeät ilmoituskuvakkeet"</string>
     <string name="other" msgid="429768510980739978">"Muu"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"poista kiekko"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"lisää kiekko loppuun"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Siirrä kiekkoa"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Lisää kiekko"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Siirrä paikkaan <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Lisää paikkaan <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Virheellinen sijainti."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"valitse käyttäjä"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Ei internetyhteyttä"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Avaa kohteen <xliff:g id="ID_1">%s</xliff:g> asetukset."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Muokkaa asetusten järjestystä."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Virtavalikko"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Sivu <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lukitusnäyttö"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(yhteys katkaistu)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Vaihtaminen ei onnistunut. Yritä uudelleen."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Yhdistä laite"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Jos haluat striimata tämän käyttökerran, avaa sovellus."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Tuntematon sovellus"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Lopeta striimaus"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Käytettävissä olevat audiolaitteet"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Siirry etusivulle"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Katso viimeisimmät sovellukset"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Valmis"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Yritä uudelleen."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Takaisin"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Pyyhkäise kosketuslevyllä vasemmalle tai oikealle kolmella sormella"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Hienoa!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Olet oppinut Takaisin-eleen."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Jos haluat palata takaisin kosketuslevyn avulla, pyyhkäise vasemmalle tai oikealle kolmella sormella"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Siirry etusivulle"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Pyyhkäise ylös kolmella sormella kosketuslevyllä"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Hienoa!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Olet oppinut eleen, jolla pääset takaisin aloitusnäytölle"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Siirry aloitusnäytölle pyyhkäisemällä kosketuslevyll\' ylös kolmella sormella"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Katso viimeisimmät sovellukset"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Pyyhkäise ylös ja pidä kosketuslevyä painettuna kolmella sormella"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Hienoa!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Olet oppinut Katso viimeisimmät sovellukset ‑eleen."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Näet äskeiset sovellukset, kun pyyhkäiset ylös ja pidät kosketuslevyä painettuna kolmella sormella."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Näytä kaikki sovellukset"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Paina näppäimistön toimintonäppäintä"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Hienoa!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Olet oppinut Näytä kaikki sovellukset ‑eleen."</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Katso kaikki sovellukset painamalla näppäimistön toimintonäppäintä"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Ohjeanimaatio, klikkaa keskeyttääksesi ja jatkaaksesi."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Näppämistön taustavalo"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Taso %1$d/%2$d"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index f55fb00..8481f0fb 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement d\'écran"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Enregistrer votre écran?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Enregistrer une appli"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Enregistrer l\'écran entier"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Enregistrer tout l\'écran : %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Lorsque vous enregistrez l\'intégralité de votre écran, tout ce qui s\'affiche sur votre écran est enregistré. Par conséquent, soyez prudent avec les mots de passe, les détails du mode de paiement, les messages, les photos et les contenus audio et vidéo."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Lorsque vous enregistrez une appli, tout ce qui est affiché ou lu dans cette appli est enregistré. Par conséquent, soyez prudent avec les mots de passe, les détails du mode de paiement, les messages, les photos et les contenus audio et vidéo."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Enregistrer l\'écran"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour le préréglage"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Préréglage"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Sélectionné"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Outils"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sous-titres instantanés"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Afficher les icônes de notification de faible priorité"</string>
     <string name="other" msgid="429768510980739978">"Autre"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"retirer la tuile"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ajouter la tuile à la fin"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Déplacer la tuile"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Ajouter la tuile"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Déplacer vers <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ajouter à la position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position incorrecte."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"choisir un utilisateur"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Aucune connexion Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Ouvrir les paramètres <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Modifier l\'ordre des paramètres."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu de l\'interrupteur"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> sur <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Écran de verrouillage"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(déconnecté)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Changement impossible. Touchez pour réessayer."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connecter un appareil"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour diffuser cette session, veuillez ouvrir l\'appli."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Appli inconnue"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Arrêter la diffusion"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Appareils disponibles pour la sortie audio."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Retour à la page d\'accueil"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Afficher les applis récentes"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"OK"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Réessayez!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Retour"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Balayez votre pavé tactile vers la gauche ou vers la droite avec trois doigts"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bien!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Vous avez appris le geste de retour en arrière."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Pour revenir en arrière à l\'aide de votre pavé tactile, balayez vers la gauche ou vers la droite avec trois doigts"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Retour à la page d\'accueil"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Balayez votre pavé tactile vers le haut avec trois doigts"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Bon travail!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Vous avez appris le geste pour revenir à l\'écran d\'accueil"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Pour accéder à votre écran d\'accueil, balayez votre pavé tactile vers le haut avec trois doigts"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Afficher les applis récentes"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Balayez votre pavé tactile vers le haut avec trois doigts, puis maintenez-les en place"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Bon travail!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Vous avez effectué le geste pour afficher les applis récentes."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Pour afficher vos applis récentes, balayez votre pavé tactile vers le haut avec trois doigts et maintenez-les en place"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Afficher toutes les applis"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Appuyez sur la touche d\'action de votre clavier"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Félicitations!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Vous avez appris le geste pour afficher toutes les applis"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Appuyez sur la touche d\'action de votre clavier pour afficher toutes vos applis"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animation du tutoriel; cliquer ici pour mettre en pause et reprendre la lecture."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Rétroéclairage du clavier"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d de %2$d"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
index 782c055..ffacde2 100644
--- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
@@ -73,7 +73,7 @@
   </string-array>
   <string-array name="tile_states_airplane">
     <item msgid="1985366811411407764">"Non disponible"</item>
-    <item msgid="4801037224991420996">"Désactivée"</item>
+    <item msgid="4801037224991420996">"Désactivé"</item>
     <item msgid="1982293347302546665">"Activé"</item>
   </string-array>
   <string-array name="tile_states_location">
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 138cfc9..80f9cd9 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement de l\'écran"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Enregistrer l\'écran ?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Enregistrer une appli"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Enregistrer tout l\'écran"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Enregistrer tout l\'écran : %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Lorsque vous enregistrez l\'intégralité de votre écran, tout ce qui s\'y affiche est enregistré. Faites donc attention aux éléments tels que les mots de passe, les détails de mode de paiement, les messages, les photos, et les contenus audio et vidéo."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Lorsque vous enregistrez une appli, tout ce qui est affiché ou lu dans celle-ci est enregistré. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages, photos et contenus audio et vidéo."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Enregistrer l\'écran"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour les préréglages"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Préréglage"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Sélectionné"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Outils"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sous-titres instantanés"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
@@ -960,9 +976,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Afficher les icônes de notification à faible priorité"</string>
     <string name="other" msgid="429768510980739978">"Autre"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"supprimer le bloc"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ajouter le bloc à la fin"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"ajouter le bloc à la dernière position"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Déplacer le bloc"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Ajouter un bloc"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Ajouter le bloc à la position souhaitée"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Déplacer vers <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ajouter à la position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Emplacement non valide."</string>
@@ -978,7 +994,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"choisir un utilisateur"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Aucun accès à Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Ouvrir les paramètres <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Modifier l\'ordre des paramètres."</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"Modifier l\'ordre des Réglages rapides."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu Marche/Arrêt"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> sur <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Écran de verrouillage"</string>
@@ -1209,7 +1225,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(déconnecté)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Impossible de changer. Appuyez pour réessayer."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connecter un appareil"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour caster cette session, veuillez ouvrir l\'appli."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Appli inconnue"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Arrêter la diffusion"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Appareils disponibles pour la sortie audio."</string>
@@ -1468,32 +1483,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Retour à l\'accueil"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Afficher les applis récentes"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"OK"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Essayez encore."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Retour"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Balayez vers la gauche ou la droite avec trois doigts sur le pavé tactile"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bravo !"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Vous avez appris le geste pour revenir en arrière"</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Pour revenir en arrière à l\'aide du pavé tactile, balayez vers la gauche ou la droite avec trois doigts"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Retour à l\'accueil"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Balayez vers le haut avec trois doigts sur le pavé tactile"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Bravo !"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Vous avez appris le geste pour revenir à l\'écran d\'accueil"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Balayez vers le haut avec trois doigts sur le pavé tactile pour accéder à l\'écran d\'accueil"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Afficher les applis récentes"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Avec trois doigts, balayez le pavé tactile vers le haut et maintenez la position"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Bravo !"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Vous avez appris le geste pour afficher les applis récentes"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Pour afficher les applis récentes, balayez le pavé tactile vers le haut avec trois doigts et maintenez la position"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Afficher toutes les applications"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Appuyez sur la touche d\'action de votre clavier"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bravo !"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Vous avez appris le geste pour afficher toutes les applis"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Appuyez sur la touche d\'action de votre clavier pour afficher toutes vos applis"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animation du tutoriel, cliquez pour mettre en pause et reprendre la lecture."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Rétroéclairage du clavier"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d sur %2$d"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index d04d043..4837954 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación de actividade en curso sobre unha sesión de gravación de pantalla"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Queres gravar a túa pantalla?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Gravar unha aplicación"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gravar pantalla completa"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Gravar pantalla completa: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Cando gravas a pantalla completa, recóllese todo o que se mostra nela. Recomendámosche que teñas coidado con determinada información, como os contrasinais, os detalles de pago, as mensaxes e as fotos, así como co contido de audio e de vídeo."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cando gravas unha aplicación, recóllese todo o que se mostra ou reproduce nela. Recomendámosche que teñas coidado con determinada información, como os contrasinais, os detalles de pago, as mensaxes e as fotos, así como co contido de audio e de vídeo."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Gravar pantalla"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Non se puido actualizar a configuración predeterminada"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Configuración predeterminada"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Elemento seleccionado"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítulos instantáneos"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar iconas das notificacións que teñan baixa prioridade"</string>
     <string name="other" msgid="429768510980739978">"Outros"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"quitar tarxeta"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"engadir tarxeta ao final"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mover tarxeta"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Engadir tarxeta"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mover a <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Engadir á posición <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posición non válida."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"escoller usuario"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Non hai conexión a Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Abrir configuración de <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editar a orde das opcións de configuración."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú de acendido"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Páxina <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueo"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desconectado)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Non se puido realizar o cambio. Toca para tentalo de novo."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Conectar un dispositivo"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para emitir esta sesión, abre a aplicación."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicación descoñecida"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Deter emisión"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos dispoñibles para a saída de audio."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Ir ao inicio"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Consultar aplicacións recentes"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Feito"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Téntao de novo."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Volver"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Pasa tres dedos cara á esquerda ou cara á dereita no panel táctil"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Excelente!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Completaches o titorial do xesto de retroceso."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Para retroceder usando o panel táctil, pasa tres dedos cara á esquerda ou cara á dereita"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Ir ao inicio"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Pasa tres dedos cara arriba no panel táctil"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Ben feito!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Completaches o titorial do xesto para ir á pantalla de inicio"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Pasa tres dedos cara arriba no panel táctil para ir á pantalla de inicio"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Consultar aplicacións recentes"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Pasa tres dedos cara arriba e mantenos premidos no panel táctil"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Moi ben!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Completaches o titorial do xesto de consultar aplicacións recentes."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Para ver as aplicacións recentes, pasa tres dedos cara arriba e mantenos premidos no panel táctil"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todas as aplicacións"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Preme a tecla de acción do teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Ben feito!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Completaches o titorial do xesto de ver todas as aplicacións"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Preme a tecla de acción do teclado para ver todas as aplicacións"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animación do titorial, fai clic para poñelo en pausa ou retomar a reprodución."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación do teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 327753d..ceefccc 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"સ્ક્રીન રેકોર્ડિંગ સત્ર માટે ચાલુ નોટિફિકેશન"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"તમારી સ્ક્રીન રેકોર્ડ કરીએ?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"એક ઍપ રેકોર્ડ કરો"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"પૂર્ણ સ્ક્રીન રેકોર્ડ કરો"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"પૂરી સ્ક્રીન રેકોર્ડ કરો: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"જ્યારે તમે તમારી પૂર્ણ સ્ક્રીન રેકોર્ડ કરી રહ્યાં હો, ત્યારે તમારી સ્ક્રીન પર બતાવવામાં આવતી હોય તેવી બધી વસ્તુ રેકોર્ડ કરવામાં આવે છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ, ફોટા અને ડિવાઇસ પર વાગી રહેલા ઑડિયો તથા વીડિયો જેવી બાબતોને લઈને સાવચેત રહો."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"જ્યારે તમે કોઈ ઍપને રેકોર્ડ કરી રહ્યાં હો, ત્યારે એ ઍપમાં બતાવવામાં કે ચલાવવામાં આવતી હોય તેવી બધી વસ્તુ રેકોર્ડ કરવામાં આવે છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ, ફોટા અને ડિવાઇસ પર વાગી રહેલા ઑડિયો તથા વીડિયો જેવી બાબતોને લઈને સાવચેત રહો."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"સ્ક્રીન રેકોર્ડ કરો"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"પ્રીસેટ અપડેટ કરી શક્યા નથી"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"પ્રીસેટ"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"પસંદ કરી છે"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ટૂલ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"લાઇવ કૅપ્શન"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"નોંધ"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"ઓછી પ્રાધાન્યતાનું નોટિફિકેશન આઇકન બતાવો"</string>
     <string name="other" msgid="429768510980739978">"અન્ય"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ટાઇલ કાઢી નાખો"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ટાઇલને અંતે ઉમેરો"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ટાઇલ ખસેડો"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"ટાઇલ ઉમેરો"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> પર ખસેડો"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"જગ્યા પર <xliff:g id="POSITION">%1$d</xliff:g> ઉમેરો"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"સ્થિતિ અમાન્ય છે."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"વપરાશકર્તા પસંદ કરો"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"કોઈ ઇન્ટરનેટ નથી"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> સેટિંગ ખોલો."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"સેટિંગના ક્રમમાં ફેરફાર કરો."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"પાવર મેનૂ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> માંથી <xliff:g id="ID_1">%1$d</xliff:g> પૃષ્ઠ"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"લૉક સ્ક્રીન"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ડિસ્કનેક્ટ કરેલું)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"સ્વિચ કરી શકતા નથી. ફરી પ્રયાસ કરવા માટે ટૅપ કરો."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"ડિવાઇસ કનેક્ટ કરો"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"આ સત્ર કાસ્ટ કરવા માટે, કૃપા કરીને ઍપ ખોલો."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"અજાણી ઍપ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"કાસ્ટ કરવાનું રોકો"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ઑડિયો આઉટપુટ માટે ઉપલબ્ધ ડિવાઇસ."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"હોમ પર જાઓ"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"તાજેતરની ઍપ જુઓ"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"થઈ ગયું"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"ફરી પ્રયાસ કરો!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"પાછા જાઓ"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"તમારા ટચપૅડ પર ત્રણ આંગળીનો ઉપયોગ કરીને ડાબે કે જમણે સ્વાઇપ કરો"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"સરસ!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"તમે પાછા જવાનો સંકેત પૂર્ણ કર્યો છે."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"તમારા ટચપૅડ વડે પાછા જવા માટે, ત્રણ આંગળીનો ઉપયોગ કરીને ડાબે કે જમણે સ્વાઇપ કરો"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"હોમ પર જાઓ"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"તમારા ટચપૅડ પર ત્રણ આંગળી વડે ઉપરની તરફ સ્વાઇપ કરો"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"ખૂબ સરસ કામ!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"તમે હોમ સ્ક્રીન પર જવાનો સંકેત પૂર્ણ કર્યો"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"તમારી હોમ સ્ક્રીન પર જવા માટે, તમારા ટચપૅડ પર ત્રણ આંગળી વડે ઉપરની તરફ સ્વાઇપ કરો"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"તાજેતરની ઍપ જુઓ"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"તમારા ટચપૅડ પર ત્રણ આંગળીઓનો ઉપયોગ કરીને ઉપર સ્વાઇપ કરો અને દબાવી રાખો"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"ખૂબ સરસ કામ!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"તમે \'તાજેતરની ઍપ જુઓ\' સંકેત પૂર્ણ કર્યો."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"તાજેતરની ઍપ જોવા માટે, તમારા ટચપૅડ પર ત્રણ આંગળી વડે ઉપરની તરફ સ્વાઇપ કરો અને દબાવી રાખો"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"બધી ઍપ જુઓ"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"તમારા કીબોર્ડ પરની ઍક્શન કી દબાવો"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"વાહ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"તમે \'બધી ઍપ જુઓ\' સંકેત પૂર્ણ કર્યો"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"તમારી બધી ઍપ જોવા માટે તમારા કીબોર્ડ પરની ઍક્શન કી દબાવો"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"ટ્યૂટૉરિઅલ ઍનિમેશન થોભાવવાનું અને ચલાવવાનું ફરી શરૂ કરવા માટે ક્લિક કરો."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"કીબોર્ડની બૅકલાઇટ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dમાંથી %1$d લેવલ"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 1d3280c..91e17df 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रिकॉर्ड सेशन के लिए जारी सूचना"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"क्या आपको स्क्रीन को रिकॉर्ड करना है?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एक ऐप्लिकेशन रिकॉर्ड करें"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"पूरी स्क्रीन रिकॉर्ड करें"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"पूरी स्क्रीन रिकॉर्ड करें: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"पूरी स्क्रीन रिकॉर्ड करते समय, स्क्रीन पर दिखने वाली हर चीज़ रिकॉर्ड की जाती है. इसलिए पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज,  डिवाइस पर चल रहे ऑडियो और वीडियो, और फ़ोटो जैसी चीज़ों को लेकर सावधानी बरतें."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"किसी ऐप्लिकेशन को रिकॉर्ड करने के दौरान, उस पर दिख रहा कॉन्टेंट या चल रहा मीडिया भी रिकॉर्ड होता है. इसलिए, रिकॉर्ड करते समय पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, ऑडियो, और वीडियो को लेकर सावधानी बरतें."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रीन रिकॉर्ड करें"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रीसेट अपडेट नहीं किया जा सका"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"प्रीसेट"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"चुना गया"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टूल"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइव कैप्शन"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"नोट"</string>
@@ -753,20 +769,13 @@
     <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"सैटलाइट कनेक्शन उपलब्ध है"</string>
     <string name="satellite_connected_carrier_text" msgid="118524195198532589">"सैटलाइट एसओएस"</string>
     <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"आपातकालीन कॉल या एसओएस"</string>
-    <!-- no translation found for accessibility_phone_string_format (7798841417881811812) -->
-    <skip />
-    <!-- no translation found for accessibility_no_signal (7052827511409250167) -->
-    <skip />
-    <!-- no translation found for accessibility_one_bar (5342012847647834506) -->
-    <skip />
-    <!-- no translation found for accessibility_two_bars (122628483354508429) -->
-    <skip />
-    <!-- no translation found for accessibility_three_bars (5143286602926069024) -->
-    <skip />
-    <!-- no translation found for accessibility_four_bars (8838495563822541844) -->
-    <skip />
-    <!-- no translation found for accessibility_signal_full (1519655809806462972) -->
-    <skip />
+    <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string>
+    <string name="accessibility_no_signal" msgid="7052827511409250167">"सिग्नल नहीं है"</string>
+    <string name="accessibility_one_bar" msgid="5342012847647834506">"एक सिग्नल बार"</string>
+    <string name="accessibility_two_bars" msgid="122628483354508429">"दो सिग्नल बार"</string>
+    <string name="accessibility_three_bars" msgid="5143286602926069024">"तीन सिग्नल बार"</string>
+    <string name="accessibility_four_bars" msgid="8838495563822541844">"चार सिग्नल बार"</string>
+    <string name="accessibility_signal_full" msgid="1519655809806462972">"सिग्नल पूरे हैं"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"वर्क प्रोफ़ाइल"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"कुछ के लिए मज़ेदार लेकिन सबके लिए नहीं"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"सिस्टम यूज़र इंटरफ़ेस (यूआई) ट्यूनर, आपको Android यूज़र इंटरफ़ेस में सुधार लाने और उसे अपनी पसंद के हिसाब से बदलने के कुछ और तरीके देता है. प्रयोग के तौर पर इस्तेमाल हो रहीं ये सुविधाएं आगे चल कर रिलीज़ की जा सकती हैं, रोकी जा सकती हैं या दिखाई देना बंद हो सकती हैं. सावधानी से आगे बढ़ें."</string>
@@ -967,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"कम प्राथमिकता वाली सूचना के आइकॉन दिखाएं"</string>
     <string name="other" msgid="429768510980739978">"अन्य"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"टाइल हटाएं"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"टाइल को आखिरी पोज़िशन पर जोड़ें"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"टाइल को किसी और पोज़िशन पर ले जाएं"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"टाइल जोड़ें"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"टाइल को <xliff:g id="POSITION">%1$d</xliff:g> पोज़िशन पर ले जाएं"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"टाइल को <xliff:g id="POSITION">%1$d</xliff:g> पोज़िशन पर जोड़ें"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"मौजूदा जगह अमान्य है."</string>
@@ -985,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"उपयोगकर्ता चुनें"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"इंटरनेट कनेक्शन नहीं है"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> सेटिंग खोलें."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"सेटिंग के क्रम को बदलें"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"पावर मेन्यू"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"पेज <xliff:g id="ID_2">%2$d</xliff:g> में से <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"लॉक स्‍क्रीन"</string>
@@ -1216,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिसकनेक्ट हो गया)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"स्विच नहीं किया जा सकता. फिर से कोशिश करने के लिए टैप करें."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"कोई डिवाइस कनेक्ट करें"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"इस सेशन को कास्ट करने के लिए, कृपया ऐप्लिकेशन खोलें."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अनजान ऐप्लिकेशन"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्ट करना बंद करें"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ऑडियो आउटपुट के लिए उपलब्ध डिवाइस."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 6fc209fb..0696dbf 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Tekuća obavijest za sesiju snimanja zaslona"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Želite li snimati zaslon?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snimanje jedne aplikacije"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snimanje cijelog zaslona"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Snimanje cijelog zaslona: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kad snimate cijeli zaslon, snima se sve što se prikazuje na zaslonu. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kad snimate aplikaciju, snima se sve što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snimanje zaslona"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje unaprijed definiranih postavki nije uspjelo"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Unaprijed definirana postavka"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Odabrano"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alati"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatski titlovi"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Napomena"</string>
@@ -960,9 +976,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Prikaži ikone obavijesti niskog prioriteta"</string>
     <string name="other" msgid="429768510980739978">"Ostalo"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"uklanjanje kartice"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"dodavanje kartice na kraj"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"dodavanje kartice na posljednji položaj"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Premještanje kartice"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Dodavanje kartice"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Dodajte karticu na željeni položaj"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Premještanje u prostoriju <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodavanje na položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Položaj nije važeći."</string>
@@ -978,7 +994,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"odaberi korisnika"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nema interneta"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otvaranje postavki za <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Uređivanje redoslijeda postavki."</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"Uredite redoslijed brzih postavki."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Izbornik tipke za uključivanje/isključivanje"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Stranica <xliff:g id="ID_1">%1$d</xliff:g> od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključani zaslon"</string>
@@ -1209,7 +1225,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nije povezano)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nije prebačeno. Dodirnite da biste pokušali ponovo."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Povežite uređaj"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste emitirali ovu sesiju, otvorite aplikaciju."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi emitiranje"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostupni uređaji za audioizlaz."</string>
@@ -1468,32 +1483,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Na početni zaslon"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Pregled nedavnih aplikacija"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gotovo"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Pokušajte ponovno!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Natrag"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Prijeđite ulijevo ili udesno trima prstima na dodirnoj podlozi"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Odlično!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Napravili ste pokret za povratak."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Da biste se vratili pomoću dodirne podloge, prijeđite trima prstima ulijevo ili udesno"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Na početnu stranicu"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Prijeđite prema gore trima prstima na dodirnoj podlozi"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Sjajno!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Napravili ste pokret za otvaranje početnog zaslona"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Da biste otvorili početni zaslon, prijeđite trima prstima prema gore na dodirnoj podlozi"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Pregled nedavnih aplikacija"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Prijeđite prema gore trima prstima na dodirnoj podlozi i zadržite pritisak"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Sjajno!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Napravili ste pokret za prikaz nedavno korištenih aplikacija."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Za prikaz nedavnih aplikacija prijeđite trima prstima prema gore na dodirnoj podlozi i zadržite pritisak"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Prikaži sve aplikacije"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite tipku za radnju na tipkovnici"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Izvrsno!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Napravili ste pokret za prikaz svih aplikacija"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Pritisnite tipku za radnju na tipkovnici za prikaz svih aplikacija"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animacija u vodiču, kliknite za pauziranje i nastavak reprodukcije."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tipkovnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Razina %1$d od %2$d"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 669d596..d2f6e8fc 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Folyamatban lévő értesítés képernyőrögzítési munkamenethez"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Rögzíti a képernyőt?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Egyetlen alkalmazás rögzítése"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Teljes képernyő rögzítése"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Teljes képernyő rögzítése: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"A teljes képernyő rögzítése esetén a képernyőn megjelenő minden tartalom rögzítésre kerül. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel, a fotókkal, valamint a hang- és videófelvételekkel."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Alkalmazás rögzítésekor az adott alkalmazásban megjelenített vagy lejátszott minden tartalom rögzítésre kerül. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel, a fotókkal, valamint a hang- és videófelvételekkel."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Képernyő rögzítése"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nem sikerült frissíteni a beállításkészletet"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Beállításkészlet"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Kiválasztva"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Eszközök"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Élő feliratozás"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Megjegyzés"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Alacsony prioritású értesítési ikonok mutatása"</string>
     <string name="other" msgid="429768510980739978">"Egyéb"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"mozaik eltávolításához"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"mozaiknak a végéhez való hozzáadásához"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mozaik áthelyezése"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Mozaik hozzáadása"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Áthelyezés ide: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Hozzáadás a következő pozícióhoz: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Érvénytelen pozíció."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"felhasználó kiválasztása"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nincs internetkapcsolat"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"A(z) <xliff:g id="ID_1">%s</xliff:g> beállításainak megnyitása."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Beállítások sorrendjének szerkesztése."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Bekapcsológombhoz tartozó menü"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. oldal, összesen: <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lezárási képernyő"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(leválasztva)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"A váltás nem sikerült. Próbálja újra."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Eszköz csatlakoztatása"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"A munkamenet átküldéséhez nyissa meg az alkalmazást."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ismeretlen alkalmazás"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Átküldés leállítása"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Rendelkezésre álló eszközök a hangkimenethez."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Ugrás a főoldalra"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Legutóbbi alkalmazások megtekintése"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Kész"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Próbálja újra"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Vissza"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Csúsztassa gyorsan három ujját balra vagy jobbra az érintőpadon."</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Remek!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Teljesítette a visszalépési kézmozdulatot."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Ha az érintőpadot használva szeretne visszalépni, csúsztasson gyorsan három ujjal balra vagy jobbra."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Ugrás a főoldalra"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Csúsztasson gyorsan felfelé három ujjával az érintőpadon."</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Kiváló!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Teljesítette a kezdőképernyőre lépés kézmozdulatát."</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"A kezdőképernyőre való ugráshoz csúsztasson gyorsan három ujjal felfelé az érintőpadon."</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Legutóbbi alkalmazások megtekintése"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Csúsztasson gyorsan felfelé három ujjal az érintőpadon, és tartsa rajta lenyomva az ujjait."</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Kiváló!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Teljesítette a legutóbbi alkalmazások megtekintésének kézmozdulatát."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"A legutóbbi appokért csúsztasson gyorsan három ujjal felfelé az érintőpadon, és tartsa lenyomva ujjait."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Összes alkalmazás megtekintése"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Nyomja meg a műveletbillentyűt az érintőpadon."</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Szép munka!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Teljesítette az összes alkalmazás megtekintésének kézmozdulatát."</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Az összes alkalmazás megtekintéséhez nyomja meg a billentyűzeten a műveletbillentyűt."</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Útmutató animáció. Kattintson a szüneteltetéshez és a lejátszás folytatásához."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"A billentyűzet háttérvilágítása"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Fényerő: %2$d/%1$d"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 095c2ad..f65f604 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Էկրանի տեսագրման աշխատաշրջանի ընթացիկ ծանուցում"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Տեսագրե՞լ ձեր էկրանը"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Տեսագրել մեկ հավելված"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Տեսագրել ամբողջ էկրանը"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Տեսագրել ամբողջ էկրանը՝ %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Երբ դուք տեսագրում եք ամբողջ էկրանը, էկրանին ցուցադրվող ամեն ինչ տեսագրվում է։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Երբ դուք որևէ հավելված եք տեսագրում, հավելվածում ցուցադրվող կամ նվագարկվող ամեն ինչ տեսագրվում է։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Տեսագրել էկրանը"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Չհաջողվեց թարմացնել կարգավորումների հավաքածուն"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Կարգավորումների հավաքածու"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Ընտրված է"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Գործիքներ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Կենդանի ենթագրեր"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Նշում"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Ցուցադրել ցածր առաջնահերթության ծանուցումների պատկերակները"</string>
     <string name="other" msgid="429768510980739978">"Այլ"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"հեռացնել սալիկը"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ավելացնել սալիկը վերջում"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Տեղափոխել սալիկը"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Ավելացնել սալիկ"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Տեղափոխել դիրք <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ավելացնել դիրք <xliff:g id="POSITION">%1$d</xliff:g>-ում"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Դիրքն անվավեր է։"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ընտրել օգտատեր"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Ինտերնետ կապ չկա"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Բացել <xliff:g id="ID_1">%s</xliff:g> կարգավորումները:"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Խմբագրել կարգավորումների հերթականությունը:"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Սնուցման կոճակի ընտրացանկ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Էջ <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Կողպէկրան"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(անջատված է)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Սխալ առաջացավ։ Հպեք՝ կրկնելու համար։"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Միացնել սարք"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Այս աշխատաշրջանը հեռարձակելու համար բացեք հավելվածը"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Անհայտ հավելված"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Կանգնեցնել հեռարձակումը"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Հասանելի սարքեր ձայնի արտածման համար։"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Ինչպես անցնել հիմնական էկրան"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Դիտել վերջին հավելվածները"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Պատրաստ է"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Նորից փորձեք։"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Հետ գնալ"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Հպահարթակի վրա երեք մատով սահեցրեք ձախ կամ աջ"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Գերազանց է"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Դուք սովորեցիք հետ գնալու ժեստը։"</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Հպահարթակին վերադառնալու համար երեք մատը սահեցրեք ձախ կամ աջ"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Անցում հիմնական էկրան"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Հպահարթակի վրա երեք մատով սահեցրեք վերև"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Կեցցե՛ք"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Դուք սովորեցիք հիմնական էկրան անցնելու ժեստը"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Հիմնական էկրանին անցնելու համար հպահարթակի վրա երեք մատը սահեցրեք վերև"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Դիտել վերջին հավելվածները"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Երեք մատով սահեցրեք վերև և սեղմած պահեք հպահարթակին"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Կեցցե՛ք"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Դուք կատարեցիք վերջին օգտագործված հավելվածների դիտման ժեստը։"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Վերջին հավելվածները տեսնելու համար երեք մատը սահեցրեք վերև և սեղմած պահեք հպահարթակին"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ինչպես դիտել բոլոր հավելվածները"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Սեղմեք գործողության ստեղնը ստեղնաշարի վրա"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Հիանալի՛ է"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Դուք սովորեցիք բոլոր հավելվածները դիտելու ժեստը"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Ձեր բոլոր հավելվածները տեսնելու համար սեղմեք գործողության ստեղնը ստեղնաշարի վրա"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Ուղեցույցի անիմացիա․ սեղմեք՝ նվագարկումը դադարեցնելու/վերսկսելու համար։"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Հետին լուսավորությամբ ստեղնաշար"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d՝ %2$d-ից"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index b5b5888..527c8e8 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifikasi yang sedang berjalan untuk sesi rekaman layar"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Rekam layar Anda?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Rekam satu aplikasi"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Rekam seluruh layar"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Rekam seluruh layar: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Saat Anda merekam seluruh layar, semua hal yang ditampilkan di layar akan direkam. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Jika Anda merekam aplikasi, semua hal yang ditampilkan atau diputar di aplikasi tersebut akan direkam. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Rekam layar"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Tidak dapat memperbarui preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Dipilih"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alat"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Teks Otomatis"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Catatan"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Tampilkan ikon notifikasi prioritas rendah"</string>
     <string name="other" msgid="429768510980739978">"Lainnya"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"menghapus kartu"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"menambahkan kartu ke akhir"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Pindahkan kartu"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Tambahkan kartu"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Pindahkan ke <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Tambahkan ke posisi <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posisi tidak valid."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"memilih pengguna"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Tidak ada internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Buka setelan <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edit urutan setelan."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu daya"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Halaman <xliff:g id="ID_1">%1$d</xliff:g> dari <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Layar kunci"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(tidak terhubung)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Tidak dapat beralih. Ketuk untuk mencoba lagi."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Hubungkan perangkat"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Buka aplikasi untuk mentransmisikan sesi ini."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikasi tidak dikenal"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Hentikan transmisi"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Perangkat yang tersedia untuk output audio."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Buka layar utama"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Lihat aplikasi terbaru"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Selesai"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Coba lagi"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kembali"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Geser ke kiri atau kanan menggunakan tiga jari di touchpad"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Sip!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Anda telah menyelesaikan gestur untuk kembali."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Untuk kembali menggunakan touchpad, geser ke kiri atau kanan menggunakan tiga jari"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Buka layar utama"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Geser ke atas dengan tiga jari di touchpad"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Bagus!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Anda telah menyelesaikan gestur buka layar utama"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Geser ke atas dengan tiga jari di touchpad untuk membuka layar utama"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Lihat aplikasi terbaru"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Geser ke atas dan tahan menggunakan tiga jari di touchpad"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Bagus!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Anda telah menyelesaikan gestur untuk melihat aplikasi terbaru."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Untuk melihat aplikasi terbaru, geser ke atas dan tahan menggunakan tiga jari di touchpad"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Lihat semua aplikasi"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tekan tombol tindakan di keyboard"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Oke!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Anda telah menyelesaikan gestur untuk melihat semua aplikasi"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Tekan tombol tindakan di keyboard untuk melihat semua aplikasi"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animasi tutorial, klik untuk menjeda dan melanjutkan pemutaran."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Lampu latar keyboard"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Tingkat %1$d dari %2$d"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index a1ad51e..3d1b025 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Áframhaldandi tilkynning fyrir skjáupptökulotu"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Viltu taka upp skjáinn?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Taka upp eitt forrit"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Taka upp allan skjáinn"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Taka upp allan skjáinn: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Þegar þú tekur upp allan skjáinn verður allt sem er sýnilegt á skjánum tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Þegar þú tekur upp forrit verður allt sem er sýnilegt eða spilað í forritinu tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Taka upp skjá"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Tókst ekki að uppfæra forstillingu"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forstilling"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valið"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verkfæri"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Skjátextar í rauntíma"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Glósa"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Sýna tákn fyrir tilkynningar með litlum forgangi"</string>
     <string name="other" msgid="429768510980739978">"Annað"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"fjarlægja flís"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"bæta flís við aftast"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Færa flís"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Bæta flís við"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Færa í <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Bæta við í stöðu <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Staða ógild."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"velja notanda"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Engin nettenging"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Opna <xliff:g id="ID_1">%s</xliff:g> stillingar."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Breyta röð stillinga."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Aflrofavalmynd"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Blaðsíða <xliff:g id="ID_1">%1$d</xliff:g> af <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lásskjár"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(aftengt)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ekki er hægt að skipta. Ýttu til að reyna aftur."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Tengja tæki"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Opnaðu forritið til að senda þessa lotu út."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Óþekkt forrit"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stöðva útsendingu"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Tæki í boði fyrir hljóðúttak."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Fara á heimaskjá"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Sjá nýleg forrit"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Lokið"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Reyndu aftur!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Til baka"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Strjúktu til hægri eða vinstri á snertifletinum með þremur fingrum"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Flott!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Þú laukst við að kynna þér bendinguna „til baka“."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Strjúktu til hægri eða vinstri á snertifletinum með þremur fingrum til að fara til baka"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Heim"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Strjúktu upp á snertifletinum með þremur fingrum"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Vel gert!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Þú framkvæmdir bendinguna „Fara á heimaskjá“"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Strjúktu upp á snertifletinum með þremur fingrum til að fara á heimaskjáinn"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Sjá nýleg forrit"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Strjúktu upp og haltu þremur fingrum inni á snertifletinum."</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Vel gert!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Þú framkvæmdir bendinguna til að sjá nýleg forrit."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Strjúktu upp og haltu þremur fingrum inni á snertifletinum til að sjá nýleg forrit"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Sjá öll forrit"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Ýttu á aðgerðalykilinn á lyklaborðinu"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Vel gert!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Þú framkvæmdir bendinguna „Sjá öll forrit“"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Ýttu á aðgerðalykilinn á lyklaborðinu´til að sjá öll forritin þín"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Leiðsagnarhreyfimynd, smelltu til að gera hlé og halda áfram að spila."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Baklýsing lyklaborðs"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Stig %1$d af %2$d"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 03a6f54..b605920 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifica costante per una sessione di registrazione dello schermo"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Registrare lo schermo?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Registra un\'app"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Registra l\'intero schermo"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Registra l\'intero schermo: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quando registri l\'intero schermo, tutto ciò che viene mostrato sullo schermo viene registrato. Presta quindi attenzione a password, dati di pagamento, messaggi, foto, audio e video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quando registri un\'app, tutto ciò che viene mostrato o riprodotto al suo interno viene registrato. Presta quindi attenzione a password, dati di pagamento, messaggi, foto, audio e video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Registra lo schermo"</string>
@@ -415,6 +417,13 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossibile aggiornare preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selezionato"</string>
+    <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Audio ambientale"</string>
+    <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Sinistra"</string>
+    <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Destra"</string>
+    <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Espandi controlli separati a sinistra e a destra"</string>
+    <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Comprimi in controllo unificato"</string>
+    <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Disattiva audio ambientale"</string>
+    <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Riattiva audio ambientale"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Strumenti"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sottotitoli in tempo reale"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
@@ -960,9 +969,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Mostra icone di notifiche con priorità bassa"</string>
     <string name="other" msgid="429768510980739978">"Altro"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"rimuovere il riquadro"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"aggiungere il riquadro alla fine"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Sposta riquadro"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Aggiungi riquadro"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Sposta nella posizione <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Aggiungi alla posizione <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posizione non valida."</string>
@@ -978,7 +989,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"selezionare l\'utente"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nessuna connessione a Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Apri le impostazioni <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Modifica l\'ordine delle impostazioni."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu del tasto di accensione"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> di <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Schermata di blocco"</string>
@@ -1209,7 +1221,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(disconnesso)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Non puoi cambiare. Tocca per riprovare."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Connetti un dispositivo"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Per trasmettere questa sessione devi aprire l\'app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App sconosciuta"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Interrompi trasmissione"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivi disponibili per l\'uscita audio."</string>
@@ -1468,32 +1479,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Vai alla schermata Home"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Visualizza app recenti"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Fine"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Riprova."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Indietro"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Scorri verso sinistra o destra con tre dita sul touchpad"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bene!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Hai completato il gesto Indietro."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Per tornare indietro usando il touchpad, scorri verso sinistra o destra con tre dita"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Vai alla schermata Home"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Scorri in alto con tre dita sul touchpad"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Ottimo lavoro!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Hai completato il gesto Vai alla schermata Home"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Scorri verso l\'alto con tre dita sul touchpad per andare alla schermata Home"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Visualizza app recenti"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Scorri verso l\'alto e tieni premuto con tre dita sul touchpad"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Ottimo lavoro!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Hai completato il gesto Visualizza app recenti."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Per visualizzare le app recenti, scorri verso l\'alto e tieni premuto con tre dita sul touchpad"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Visualizza tutte le app"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Premi il tasto azione sulla tastiera"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Ben fatto!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Hai completato il gesto Visualizza tutte le app."</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Premi il tasto azione sulla tastiera per visualizzare tutte le tue app"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animazione del tutorial: fai clic per mettere in pausa e riprendere la riproduzione."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroilluminazione della tastiera"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Livello %1$d di %2$d"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 1d74a49..d0f26ba 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"התראה מתמשכת לסשן הקלטת מסך"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"להקליט את המסך?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"הקלטה של אפליקציה אחת"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"הקלטה של כל המסך"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"‏הקלטת התוכן של כל המסך: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"כשמקליטים את כל המסך, כל מה שמופיע במסך מוקלט. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"כשמקליטים אפליקציה, כל מה שרואים או מפעילים בה מוקלט. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"הקלטת המסך"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"לא ניתן לעדכן את ההגדרה הקבועה מראש"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"הגדרה קבועה מראש"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"נבחר"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"כלים"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"כתוביות מיידיות"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"פתק"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"הצגת סמלי התראות בעדיפות נמוכה"</string>
     <string name="other" msgid="429768510980739978">"אחר"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"הסרת הלחצן"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"הוספת הלחצן בסוף הרשימה"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"העברת הלחצן"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"הוספת לחצן"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"העברה למיקום <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"הוספה למיקום <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"המיקום לא תקין."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"בחירת משתמש"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"אין אינטרנט"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"פתיחת הגדרות של <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"עריכת סדר ההגדרות."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"תפריט הפעלה"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"דף <xliff:g id="ID_1">%1$d</xliff:g> מתוך <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"מסך נעילה"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(מנותק)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"לא ניתן להחליף. צריך להקיש כדי לנסות שוב."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"חיבור מכשיר"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"‏כדי להפעיל Cast של הסשן הזה, צריך לפתוח את האפליקציה."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"אפליקציה לא ידועה"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"‏עצירת ההעברה (casting)"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"מכשירים זמינים לפלט אודיו."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"חזרה לדף הבית"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"הצגת האפליקציות האחרונות"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"סיום"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"צריך לנסות שוב."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"חזרה"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"מחליקים שמאלה או ימינה עם שלוש אצבעות על לוח המגע"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"איזה יופי!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"סיימת לתרגל את התנועה \'הקודם\'."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"כדי לחזור אחורה באמצעות לוח המגע, צריך להחליק שמאלה או ימינה עם שלוש אצבעות"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"מעבר למסך הבית"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"מחליקים כלפי מעלה עם שלוש אצבעות על לוח המגע"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"מעולה!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"סיימת לתרגל את תנועת החזרה למסך הבית"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"כדי לעבור למסך הבית, צריך להחליק כלפי מעלה עם שלוש אצבעות על לוח המגע"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"הצגת האפליקציות האחרונות"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"מחליקים למעלה עם שלוש אצבעות על לוח המגע ומשאירים אותן במגע עם הלוח"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"מעולה!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"סיימת לתרגל את התנועה להצגת האפליקציות האחרונות."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"כדי לראות את האפליקציות האחרונות, צריך להחליק למעלה וללחוץ לחיצה ארוכה עם שלוש אצבעות על לוח המגע"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"צפייה בכל האפליקציות"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"צריך להקיש על מקש הפעולה במקלדת"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"כל הכבוד!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"סיימת לתרגל את התנועה להצגת כל האפליקציות"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"כדי לראות את כל האפליקציות, צריך להקיש על מקש הפעולה במקלדת"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"אנימציה של הדרכה, אפשר ללחוץ כדי להשהות ולהמשיך את ההפעלה."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"התאורה האחורית במקלדת"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏רמה %1$d מתוך %2$d"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index da74e23..dd9eb2a 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"画面の録画セッション中の通知"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"画面を録画しますか?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"1 つのアプリを録画"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"画面全体を録画"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"画面全体を録画: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"画面全体を録画すると、画面に表示されるものがすべて録画されます。パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"アプリを録画すると、そのアプリで表示または再生される内容がすべて録画されます。パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"画面を録画"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"プリセットを更新できませんでした"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"プリセット"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"選択中"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ツール"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"自動字幕起こし"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"注"</string>
@@ -960,9 +976,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"優先度の低い通知アイコンを表示"</string>
     <string name="other" msgid="429768510980739978">"その他"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"タイルを削除"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"タイルを最後に追加"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"タイルを最後の位置に追加する"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"タイルを移動"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"タイルを追加"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"タイルを目的の位置に追加する"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> に移動"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"ポジション <xliff:g id="POSITION">%1$d</xliff:g> に追加"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置が無効です。"</string>
@@ -978,7 +994,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ユーザーを選択"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"インターネットに接続されていません"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> の設定を開きます。"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"設定の順序を編集します。"</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"クイック設定の順序を編集します。"</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"電源ボタン メニュー"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ページ <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ロック画面"</string>
@@ -1209,7 +1225,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(接続解除済み)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"切り替えられません。タップしてやり直してください。"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"デバイスを接続"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"このセッションをキャストするには、アプリを開いてください。"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明なアプリ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"キャストを停止"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"音声出力ができるデバイスです。"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 5a20158..e2459f3 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"უწყვეტი შეტყობინება ეკრანის ჩაწერის სესიისთვის"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"გსურთ თქვენი ეკრანის ჩაწერა?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ერთი აპის ჩაწერა"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"მთლიანი ეკრანის ჩაწერა"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"მთლიანი ეკრანის ჩაწერა: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"მთლიანი ეკრანის ჩაწერისას ჩაიწერება ყველაფერი, რაც თქვენს ეკრანზე გამოჩნდება. ამიტომ სიფრთხილე გამოიჩინეთ ისეთ ინფორმაციასთან, როგორიცაა პაროლები, გადახდის დეტალები, შეტყობინებები, ფოტოები, აუდიო და ვიდეო."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"აპის ჩაწერისას ჩაიწერება ყველაფერი, რაც ამ აპში გამოჩნდება ან დაიკვრება. ამიტომ სიფრთხილე გამოიჩინეთ ისეთ ინფორმაციასთან, როგორიცაა პაროლები, გადახდის დეტალები, შეტყობინებები, ფოტოები, აუდიო და ვიდეო."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ეკრანის ჩაწერა"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"წინასწარ დაყენებული პარამეტრების განახლება ვერ მოხერხდა"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"წინასწარ დაყენებული"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"არჩეულია"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ხელსაწყოები"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ავტოსუბტიტრები"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"ჩანიშვნა"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"დაბალი პრიორიტეტის მქონე შეტყობინებების ხატულების ჩვენება"</string>
     <string name="other" msgid="429768510980739978">"სხვა"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"მოზაიკის ფილის წაშლა"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ფილის ბოლოში დამატება"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"მოზაიკის გადატანა"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"მოზაიკის დამატება"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"გადატანა <xliff:g id="POSITION">%1$d</xliff:g>-ზე"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"დამატება პოზიციაზე <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"პოზიცია არასწორია."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"მომხმარებლის არჩევა"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ინტერნეტ-კავშირი არ არის"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> პარამეტრების გახსნა."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"პარამეტრების მიმდევრობის რედაქტირება."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ჩართვის მენიუ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"გვერდი <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>-დან"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ჩაკეტილი ეკრანი"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(კავშირი გაწყვეტილია)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ვერ გადაირთო. შეეხეთ ხელახლა საცდელად."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"მოწყობილობასთან დაკავშირება"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ამ სესიის ტრანსლირებისთვის გახსენით აპი."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"უცნობი აპი"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ტრანსლირების შეწყვეტა"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ხელმისაწვდომი მოწყობილობები გამომავალი აუდიოსთვის."</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 5bd63b1..c325c96 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды бейнеге жазудың ағымдағы хабарландыруы"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Қолданба экранын жазасыз ба?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Бір қолданба экранын жазу"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Бүкіл экранды жазу"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Бүкіл экранды жазу: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Бүкіл экранды жазған кезде, онда көрінетін барлық нәрсе жазылады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Қолданбаны жазған кезде, онда көрінетін не ойнатылатын барлық нәрсе жазылады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Экранды жазу"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Параметрлер жинағын жаңарту мүмкін болмады."</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Параметрлер жинағы"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Таңдалды"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Құралдар"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Ескертпе"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Маңызды емес хабарландыру белгішелерін көрсету"</string>
     <string name="other" msgid="429768510980739978">"Басқа"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"бөлшекті өшіру"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"бөлшекті соңына қосу"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Бөлшекті жылжыту"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Бөлшек қосу"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> орнына жылжыту"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> орнына қосу"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Орын жарамсыз."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"пайдаланушыны таңдаңыз"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Интернетпен байланыс жоқ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> параметрлерін ашу."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Параметрлер тәртібін өзгерту."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Қуат мәзірі"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ішінен <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Құлыптаулы экран"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ажыратулы)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Ауысу мүмкін емес. Әрекетті қайталау үшін түртіңіз."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Құрылғы жалғау"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Бұл сеансты трансляциялау үшін қолданбаны ашыңыз."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Белгісіз қолданба"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Трансляцияны тоқтату"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Аудио шығыс үшін қолжетімді құрылғылар бар."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Негізгі бетке өту"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Соңғы қолданбаларды көру"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Дайын"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Қайталап көріңіз"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Артқа"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Сенсорлық тақтада үш саусақпен оңға немесе солға сырғытыңыз."</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Керемет!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Артқа қайту қимылын аяқтадыңыз."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Сенсорлық тақта арқылы артқа оралу үшін үш саусақпен солға немесе оңға сырғытыңыз."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Негізгі экранға өту"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Сенсорлық тақтада үш саусақпен жоғары сырғытыңыз."</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Жарайсыз!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Негізгі экранға қайту қимылын орындадыңыз."</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Негізгі экранға өту үшін сенсорлық тақтада үш саусақпен жоғары сырғытыңыз."</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Соңғы қолданбаларды көру"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Сенсорлық тақтада үш саусақпен жоғары сырғытып, басып тұрыңыз."</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Жарайсыз!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Соңғы қолданбаларды көру қимылын орындадыңыз."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Соңғы қолданбаларды көру үшін сенсорлық тақтада үш саусақпен жоғары сырғытып, ұстап тұрыңыз."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Барлық қолданбаны көру"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Пернетақтадағы әрекет пернесін басыңыз."</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Жарайсыз!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Барлық қолданбаны көру қимылын орындадыңыз."</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Барлық қолданбаңызды көру үшін пернетақтадағы әрекет пернесін басыңыз."</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Оқулықтың анимациясы, ойнатуды кідірту және жалғастыру үшін басыңыз."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Пернетақта жарығы"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Деңгей: %1$d/%2$d"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index fa3fc664..a6e25d1 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ការជូនដំណឹង​ដែល​កំពុង​ដំណើរការ​សម្រាប់​រយៈពេលប្រើ​ការថត​សកម្មភាព​អេក្រង់"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ថត​អេក្រង់​របស់អ្នកឬ?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ថត​កម្មវិធី​ទោល"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ថតអេក្រង់ទាំងមូល"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ថតអេក្រង់ទាំងមូល៖ %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"នៅពេល​អ្នកកំពុង​ថតអេក្រង់​ទាំងមូល​របស់អ្នក អ្វីគ្រប់យ៉ាង​ដែលបង្ហាញ​នៅលើ​អេក្រង់​របស់អ្នក​ត្រូវបាន​ថត។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះអ្វីៗដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ សារ រូបថត ព្រមទាំងសំឡេង និងវីដេអូ។"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"នៅពេលអ្នក​កំពុង​ថតកម្មវិធី​ណាមួយ អ្វីគ្រប់យ៉ាង​ដែលបង្ហាញ ឬចាក់​នៅក្នុង​កម្មវិធីនោះ​ត្រូវបាន​ថត។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះអ្វីៗដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ សារ រូបថត ព្រមទាំងសំឡេង និងវីដេអូ។"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ថត​អេក្រង់"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"មិនអាច​ប្ដូរ​ការកំណត់ជាមុន​បានទេ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"កំណត់ជាមុន"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"បានជ្រើសរើស"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ឧបករណ៍"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"អក្សររត់ក្នុងពេលជាក់ស្ដែង"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"កំណត់ចំណាំ"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"បង្ហាញ​រូប​ការជូនដំណឹង​ដែលមានអាទិភាពទាប"</string>
     <string name="other" msgid="429768510980739978">"ផ្សេងៗ"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ដកប្រអប់ចេញ"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"បញ្ចូល​ប្រអប់ទៅ​ខាងចុង"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ផ្លាស់ទី​ប្រអប់"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"បញ្ចូល​ប្រអប់"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"ផ្លាស់​ទីទៅ <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"បញ្ចូលទៅ​ទីតាំងទី <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ទីតាំងគ្មានសុពលភាព។"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ជ្រើសរើស​អ្នកប្រើប្រាស់"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"គ្មាន​អ៊ីនធឺណិតទេ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"បើការកំណត់ <xliff:g id="ID_1">%s</xliff:g>"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"កែលំដាប់ការកំណត់"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ម៉ឺនុយ​ថាមពល"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ទំព័រ <xliff:g id="ID_1">%1$d</xliff:g> នៃ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"អេក្រង់​ចាក់សោ"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(បាន​ដាច់)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"មិនអាចប្ដូរបានទេ។ សូមចុចដើម្បី​ព្យាយាម​ម្ដងទៀត។"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"ភ្ជាប់​ឧបករណ៍"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ដើម្បីភ្ជាប់វគ្គនេះ សូមបើកកម្មវិធី។"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"កម្មវិធី​ដែលមិន​ស្គាល់"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"បញ្ឈប់ការភ្ជាប់"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ឧបករណ៍​ដែលអាច​ប្រើបាន​សម្រាប់ឧបករណ៍​បញ្ចេញ​សំឡេង។"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index e53988c..2ddb1a8 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೆಶನ್‌ಗಾಗಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ನೋಟಿಫಿಕೇಶನ್"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಬೇಕೇ?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ಒಂದು ಆ್ಯಪ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಿ: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ನಿಮ್ಮ ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ ಅನ್ನು ನೀವು ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತಿರುವಾಗ, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ ಮೇಲೆ ಗೋಚರಿಸುವ ಎಲ್ಲವನ್ನೂ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಮತ್ತು ಆಡಿಯೋ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಬಗ್ಗೆ ಜಾಗರೂಕರಾಗಿರಿ."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡುವಾಗ, ಆ ಆ್ಯಪ್‌ನಲ್ಲಿ ತೋರಿಸಿರುವ ಅಥವಾ ಪ್ಲೇ ಮಾಡಿದ ಎಲ್ಲವನ್ನೂ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಮತ್ತು ಆಡಿಯೋ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಬಗ್ಗೆ ಜಾಗರೂಕರಾಗಿರಿ."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ಪ್ರಿಸೆಟ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ಪ್ರಿಸೆಟ್‌"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ಟೂಲ್‌ಗಳು"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ಲೈವ್ ಕ್ಯಾಪ್ಶನ್"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"ಟಿಪ್ಪಣಿ"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"ಕಡಿಮೆ-ಆದ್ಯತೆ ಸೂಚನೆಯ ಐಕಾನ್‌ಗಳನ್ನು ತೋರಿಸಿ"</string>
     <string name="other" msgid="429768510980739978">"ಇತರ"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ಟೈಲ್ ಅನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ಕೊನೆಯಲ್ಲಿ ಟೈಲ್ ಸೇರಿಸಿ"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ಟೈಲ್ ಸರಿಸಿ"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"ಟೈಲ್ ಸೇರಿಸಿ"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"ಇಲ್ಲಿಗೆ ಸರಿಸಿ <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ಸ್ಥಾನಕ್ಕೆ ಸೇರಿಸಿ"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ಸ್ಥಾನವು ಅಮಾನ್ಯವಾಗಿದೆ."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ಬಳಕೆದಾರರನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ಸೆಟ್ಟಿಂಗ್‌ಗಳ ಕ್ರಮವನ್ನು ಎಡಿಟ್ ಮಾಡಿ."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ಪವರ್ ಮೆನು"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="ID_1">%1$d</xliff:g> ಪುಟ"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ಲಾಕ್ ಸ್ಕ್ರೀನ್"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ಡಿಸ್‌ಕನೆಕ್ಟ್ ಆಗಿದೆ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ಬದಲಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"ಸಾಧನವನ್ನು ಕನೆಕ್ಟ್ ಮಾಡಿ"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ಈ ಸೆಶನ್ ಕಾಸ್ಟ್ ಮಾಡಲು, ಆ್ಯಪ್ ಅನ್ನು ತೆರೆಯಿರಿ."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ಅಪರಿಚಿತ ಆ್ಯಪ್"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ಬಿತ್ತರಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಿ"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ಆಡಿಯೋ ಔಟ್‌ಪುಟ್‌ಗಾಗಿ ಲಭ್ಯವಿರುವ ಸಾಧನಗಳು."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"ಮುಖಪುಟಕ್ಕೆ ಹೋಗಿ"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ಮುಗಿದಿದೆ"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"ಪುನಃ ಪ್ರಯತ್ನಿಸಿ!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ಹಿಂತಿರುಗಿ"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"ನಿಮ್ಮ ಟಚ್‌ಪ್ಯಾಡ್‌ನಲ್ಲಿ ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಎಡ ಅಥವಾ ಬಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"ಚೆನ್ನಾಗಿದೆ!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"ನೀವು ಗೋ ಬ್ಯಾಕ್ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"ನಿಮ್ಮ ಟಚ್‌ಪ್ಯಾಡ್ ಬಳಸಿಕೊಂಡು ಹಿಂತಿರುಗಲು, ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಎಡಕ್ಕೆ ಅಥವಾ ಬಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"ಮುಖಪುಟಕ್ಕೆ ಹೋಗಿ"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"ಟಚ್‌ಪ್ಯಾಡ್‌ನಲ್ಲಿ ಮೂರು ಬೆರಳಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"ಭೇಷ್!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"ನೀವು ಗೋ ಹೋಮ್ ಜೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ಗೆ ಹೋಗಲು ನಿಮ್ಮ ಟಚ್‌ಪ್ಯಾಡ್‌ನಲ್ಲಿ ಮೂರು ಬೆರಳುಗಳಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"ನಿಮ್ಮ ಟಚ್‌ಪ್ಯಾಡ್‌ನಲ್ಲಿ ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"ಭೇಷ್‌!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ನೀವು ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳ ಜೆಸ್ಚರ್‌ ವೀಕ್ಷಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಲು, ನಿಮ್ಮ ಟಚ್‌ಪ್ಯಾಡ್‌ನಲ್ಲಿ ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್‌ನಲ್ಲಿ ಆ್ಯಕ್ಷನ್‌ ಕೀಯನ್ನು ಒತ್ತಿ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ಭೇಷ್!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ನೀವು ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳ ಜೆಸ್ಚರ್‌ ವೀಕ್ಷಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"ನಿಮ್ಮ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಲು ನಿಮ್ಮ ಕೀಬೋರ್ಡ್‌ನಲ್ಲಿ ಆ್ಯಕ್ಷನ್‌ ಕೀಯನ್ನು ಒತ್ತಿ"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"ಟುಟೋರಿಯಲ್ ಆ್ಯನಿಮೇಷನ್, ವಿರಾಮಗೊಳಿಸಲು ಮತ್ತು ಪ್ಲೇ ಪುನರಾರಂಭಿಸಲು ಕ್ಲಿಕ್ ಮಾಡಿ."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ಕೀಬೋರ್ಡ್ ಬ್ಯಾಕ್‌ಲೈಟ್"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ರಲ್ಲಿ %1$d ಮಟ್ಟ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index dc6fcda..caa7634 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"화면 녹화 세션에 관한 지속적인 알림"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"화면을 녹화하시겠습니까?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"단일 앱 녹화"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"전체 화면 녹화"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"전체 화면 녹화: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"전체 화면을 녹화하면 화면에 표시되는 모든 항목이 녹화됩니다. 따라서 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"앱을 녹화하면 앱에 표시되거나 앱에서 재생되는 모든 항목이 녹화됩니다. 따라서 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"화면 녹화"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"사전 설정을 업데이트할 수 없음"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"미리 설정"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"선택됨"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"도구"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"실시간 자막"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"메모"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"우선순위가 낮은 알림 아이콘 표시"</string>
     <string name="other" msgid="429768510980739978">"기타"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"타일 삭제"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"끝에 타일 추가"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"타일 이동"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"타일 추가"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> 위치로 이동"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> 위치에 추가"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"위치가 잘못되었습니다."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"사용자 선택"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"인터넷 연결 없음"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> 설정 열기"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"설정 순서 수정"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"전원 메뉴"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>페이지 중 <xliff:g id="ID_1">%1$d</xliff:g>페이지"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"잠금 화면"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(연결 끊김)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"전환할 수 없습니다. 다시 시도하려면 탭하세요."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"기기 연결"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"세션을 전송하려면 앱을 열어 주세요"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"알 수 없는 앱"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"전송 중지"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"오디오 출력에 사용 가능한 기기입니다."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"홈으로 이동"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"최근 앱 보기"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"완료"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"다시 시도해 보세요"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"뒤로"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"세 손가락을 사용해 터치패드에서 왼쪽 또는 오른쪽으로 스와이프하세요."</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"훌륭합니다"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"돌아가기 동작을 완료했습니다."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"터치패드를 사용해 뒤로 돌아가려면 세 손가락을 사용해 왼쪽이나 오른쪽으로 스와이프하세요."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"홈으로 이동"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"세 손가락을 사용해 터치패드에서 위로 스와이프하세요."</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"잘하셨습니다"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"홈으로 이동 동작을 완료했습니다."</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"홈 화면으로 이동하려면 터치패드에서 세 손가락을 사용해 위로 스와이프하세요."</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"최근 앱 보기"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"세 손가락을 사용해 터치패드에서 위로 스와이프한 후 잠시 기다리세요."</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"아주 좋습니다"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"최근 앱 보기 동작을 완료했습니다."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"최근 앱을 보려면 터치패드에서 세 손가락을 사용해 위로 스와이프한 채로 유지하세요."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"모든 앱 보기"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"키보드의 작업 키를 누르세요."</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"잘하셨습니다"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"모든 앱 보기 동작을 완료했습니다."</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"모든 앱을 확인하려면 키보드의 작업 키를 누르세요."</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"튜토리얼 애니메이션입니다. 일시중지하고 재생을 재개하려면 클릭하세요."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"키보드 백라이트"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d단계 중 %1$d단계"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 83ec250..836179e 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Экранды жаздырасызбы?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Бир колдонмону жаздыруу"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Бүтүндөй экранды жаздыруу"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Толук экранды жаздыруу: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Бүтүндөй экранды жаздырганда, андагы нерселердин баары видеого түшүп калат. Андыктан этият болуп, сырсөздөр, төлөм ыкмалары, билдирүүлөр, сүрөттөр, аудио жана видео материалдар сыяктуу купуя нерселерди көрсөтүп албаңыз."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Колдонмону жаздырганда, андагы нерселердин баары видеого түшүп калат. Андыктан сырсөздөр, төлөмдүн чоо-жайы, билдирүүлөр, сүрөттөр, аудио жана видео сыяктуу нерселер менен этият болуңуз."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Экранды жаздыруу"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Алдын ала коюлган параметрлер жаңыртылган жок"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Алдын ала коюлган параметрлер"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Тандалды"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Куралдар"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Ыкчам коштомо жазуулар"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Учкай маалымат"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Анча маанилүү эмес билдирменин сүрөтчөлөрүн көрсөтүү"</string>
     <string name="other" msgid="429768510980739978">"Башка"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ыкчам баскычты өчүрүү"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ыкчам баскычты аягына кошуу"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Ыкчам баскычты жылдыруу"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Ыкчам баскыч кошуу"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Төмөнкүгө жылдыруу: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g>-позицияга кошуу"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Абал жараксыз."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"колдонуучуну тандоо"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Интернет жок"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> параметрлерин ачуу."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Параметрлердин иретин өзгөртүү."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Кубат баскычынын менюсу"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ичинен <xliff:g id="ID_1">%1$d</xliff:g>-бет"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Кулпуланган экран"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ажыратылды)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Которулбай жатат. Кайталоо үчүн басыңыз."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Түзмөктү туташтыруу"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Бул сеансты тышкы экранга чыгаруу үчүн колдонмону ачыңыз."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Белгисиз колдонмо"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Тышкы экранга чыгарууну токтотуу"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Аудио чыгаруу үчүн жеткиликтүү түзмөктөр."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Башкы бетке өтүү"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Акыркы колдонмолорду көрүү"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Бүттү"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Кайталап көрүңүз!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Артка кайтуу"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Сенсордук тактаны үч манжаңыз менен солго же оңго сүрүңүз"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Сонун!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"\"Артка\" жаңсоосун үйрөндүңүз."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Сенсордук такта менен артка кайтуу үчүн үч манжаңыз менен солго же оңго сүрүңүз"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Башкы бетке өтүү"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Сенсордук тактаны үч манжаңыз менен жогору сүрүңүз"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Азаматсыз!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"\"Башкы бетке өтүү\" жаңсоосун үйрөндүңүз"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Башкы экранга өтүү үчүн сенсордук тактаны үч манжаңыз менен жогору сүрүңүз"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Акыркы колдонмолорду көрүү"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Сенсордук тактаны үч манжаңыз менен өйдө сүрүп, кармап туруңуз"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Азаматсыз!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Акыркы колдонмолорду көрүү жаңсоосун аткардыңыз."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Соңку колдонмолорду көрүү үчүн сенсордук тактаны үч манжаңыз менен жогору сүрүп, кармап туруңуз"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Бардык колдонмолорду көрүү"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Баскычтобуңуздагы аракет баскычын басыңыз"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Эң жакшы!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Бардык колдонмолорду көрүү жаңсоосун аткардыңыз"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Бардык колдонмолоруңузду көрүү үчүн баскычтобуңуздагы аракет баскычын басыңыз"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Үйрөткүч анимация, ойнотууну тындыруу же улантуу үчүн чыкылдатыңыз."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Баскычтоптун жарыгы"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ичинен %1$d-деңгээл"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 53d3bca..47a431b 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ການແຈ້ງເຕືອນສຳລັບເຊດຊັນການບັນທຶກໜ້າຈໍໃດໜຶ່ງ"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ບັນທຶກໜ້າຈໍຂອງທ່ານບໍ?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ບັນທຶກແອັບດຽວ"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ບັນທຶກໝົດໜ້າຈໍ"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ບັນທຶກໜ້າຈໍທັງໝົດ: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ເມື່ອທ່ານບັນທຶກໝົດໜ້າຈໍຂອງທ່ານ, ລະບົບຈະບັນທຶກທຸກສິ່ງທີ່ສະແດງຢູ່ໜ້າຈໍຂອງທ່ານ. ດັ່ງນັ້ນ, ໃຫ້ລະມັດລະວັງສິ່ງຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ, ຮູບພາບ, ພ້ອມທັງສຽງ ແລະ ວິດີໂອ."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ເມື່ອທ່ານບັນທຶກແອັບ, ລະບົບຈະບັນທຶກທຸກສິ່ງທີ່ສະແດງ ຫຼື ຫຼິ້ນຢູ່ໃນແອັບນັ້ນ. ດັ່ງນັ້ນ, ໃຫ້ລະມັດລະວັງສິ່ງຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ, ຮູບພາບ, ພ້ອມທັງສຽງ ແລະ ວິດີໂອ."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ບັນທຶກໜ້າຈໍ"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ບໍ່ສາມາດອັບເດດການຕັ້ງຄ່າລ່ວງໜ້າໄດ້"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ຄ່າທີ່ກຳນົດລ່ວງໜ້າ"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ເລືອກແລ້ວ"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ເຄື່ອງມື"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ຄຳບັນຍາຍສົດ"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"ບັນທຶກ"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"ສະແດງໄອຄອນການແຈ້ງເຕືອນຄວາມສຳຄັນຕ່ຳ"</string>
     <string name="other" msgid="429768510980739978">"ອື່ນໆ"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ລຶບແຜ່ນອອກ"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ເພີ່ມແຜ່ນໃສ່ທ້າຍ"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ຍ້າຍແຜ່ນ"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"ເພີ່ມແຜ່ນ"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"ຍ້າຍໄປ <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"ເພີ່ມໃສ່ຕຳແໜ່ງ <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ຕຳແໜ່ງບໍ່ຖືກຕ້ອງ."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ເລືອກຜູ້ໃຊ້"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ບໍ່ມີອິນເຕີເນັດ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"ເປີດການຕັ້ງຄ່າ <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ແກ້ໄຂລຳດັບການຕັ້ງຄ່າ."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ເມນູເປີດປິດ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g> ຈາກທັງໝົດ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ໜ້າຈໍລັອກ"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ຕັດການເຊື່ອມຕໍ່ແລ້ວ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ບໍ່ສາມາດສະຫຼັບໄດ້. ແຕະເພື່ອລອງໃໝ່."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"ເຊື່ອມຕໍ່ຫາອຸປະກອນ"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ເພື່ອສົ່ງສັນຍານເຊດຊັນນີ້, ກະລຸນາເປີດແອັບ."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ແອັບທີ່ບໍ່ຮູ້ຈັກ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ຢຸດການສົ່ງສັນຍານ"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ອຸປະກອນທີ່ສາມາດໃຊ້ໄດ້ສຳລັບເອົ້າພຸດສຽງ."</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index bfdd89f..5fba5b2 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Šiuo metu rodomas ekrano įrašymo sesijos pranešimas"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Įrašyti ekraną?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Įrašyti vieną programą"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Įrašyti visą ekraną"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Įrašyti visą ekraną: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kai įrašote visą ekraną, įrašomas visas ekrane rodomas turinys. Todėl būkite atsargūs naudodami slaptažodžius, išsamią mokėjimo metodo informaciją, pranešimus, nuotraukas ir garso bei vaizdo įrašus."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kai įrašote programą, įrašomas visas toje programoje rodomas ar leidžiamas turinys. Todėl būkite atsargūs naudodami slaptažodžius, išsamią mokėjimo metodo informaciją, pranešimus, nuotraukas ir garso bei vaizdo įrašus."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Įrašyti ekraną"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Išankstinių nustatymų atnaujinti nepavyko"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Išankstiniai nustatymai"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Pasirinkta"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Įrankiai"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitrai realiuoju laiku"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Pastaba"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Rodyti mažo prioriteto pranešimų piktogramas"</string>
     <string name="other" msgid="429768510980739978">"Kita"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"pašalintumėte išklotinės elementą"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"pridėtumėte išklotinės elementą gale"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Perkelti išklotinės elementą"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Pridėti išklotinės elementą"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Perkelkite į <xliff:g id="POSITION">%1$d</xliff:g> poziciją"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Pridėkite <xliff:g id="POSITION">%1$d</xliff:g> pozicijoje"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Padėtis netinkama."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"pasirinktumėte naudotoją"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nėra interneto ryšio"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Atidaryti „<xliff:g id="ID_1">%s</xliff:g>“ nustatymus."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Redaguoti nustatymų tvarką."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Įjungimo meniu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g> psl. iš <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Užrakinimo ekranas"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(atjungta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nepavyko perjungti. Bandykite vėl palietę."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Įrenginio prijungimas"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Jei norite perduoti šį seansą, atidarykite programą."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nežinoma programa"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Sustabdyti perdavimą"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Pasiekiami garso išvesties įrenginiai."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 9208c7e..a407750 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Aktīvs paziņojums par ekrāna ierakstīšanas sesiju"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vai ierakstīt ekrānu?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Ierakstīt vienu lietotni"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Ierakstīt visu ekrānu"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Ierakstīt visu ekrānu: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Ierakstot visu ekrānu, viss, kas redzams ekrānā, tiek ierakstīts. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Ierakstot lietotni, tiek ierakstīts viss attiecīgajā lietotnē rādītais vai atskaņotais. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ierakstīt ekrānu"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nevarēja atjaunināt pirmsiestatījumu"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Pirmsiestatījums"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Atlasīts"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Rīki"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitri reāllaikā"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Piezīme"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Rādīt zemas prioritātes paziņojumu ikonas"</string>
     <string name="other" msgid="429768510980739978">"Citi"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"noņemt elementu"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"pievienot elementu beigās"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Pārvietot elementu"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Pievienot elementu"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Pārvietot uz pozīciju numur <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Pievienot elementu pozīcijā numur <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nederīga pozīcija."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"izvēlēties lietotāju"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nav piekļuves internetam"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Atvērt <xliff:g id="ID_1">%s</xliff:g> iestatījumus."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Rediģēt iestatījumu secību."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Barošanas izvēlne"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. lpp. no <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Bloķēšanas ekrāns"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(savienojums pārtraukts)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nevar pārslēgt. Pieskarieties, lai mēģinātu vēlreiz."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Savienot ar ierīci"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Lai apraidītu šo sesiju, lūdzu, atveriet lietotni."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nezināma lietotne"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Apturēt apraidi"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Audio izvadei pieejamās ierīces."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Pāriet uz sākuma ekrānu"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Skatīt nesen izmantotās lietotnes"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gatavs"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Mēģiniet vēlreiz."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Atpakaļ"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Skārienpaliktnī ar trīs pirkstiem velciet pa kreisi vai pa labi."</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Lieliski!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Jūs sekmīgi veicāt atgriešanās žestu."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Lai pārietu atpakaļ, izmantojot skārienpaliktni, ar trīs pirkstiem velciet pa kreisi vai pa labi"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Pāreja uz sākuma ekrānu"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Skārienpaliktnī ar trīs pirkstiem velciet augšup."</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Lieliski!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Jūs sekmīgi veicāt sākuma ekrāna atvēršanas žestu."</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Lai pārietu uz sākuma ekrānu, skārienpaliktnī ar trīs pirkstiem velciet augšup"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Nesen izmantoto lietotņu skatīšana"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Skārienpaliktnī ar trīs pirkstiem velciet augšup un turiet."</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Lieliski!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Jūs sekmīgi veicāt nesen izmantoto lietotņu skatīšanas žestu."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Lai skatītu nesenās lietotnes, skārienpaliktnī ar trīs pirkstiem velciet augšup un turiet"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Skatīt visas lietotnes"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tastatūrā nospiediet darbību taustiņu."</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Lieliski!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Jūs sekmīgi veicāt visu lietotņu skatīšanas žestu."</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Lai skatītu visas savas lietotnes, tastatūrā nospiediet darbību taustiņu."</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Mācību animācija. Noklikšķiniet, lai pārtrauktu un atsāktu atskaņošanu."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastatūras fona apgaismojums"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Līmenis numur %1$d, kopā ir %2$d"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 15f2435..f71ca44 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Тековно известување за сесија за снимање на екранот"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Да се снима екранот?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Снимање на една апликација"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Снимање на целиот екран"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Снимање на целиот екран: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Додека го снимате целиот екран, сѐ што е прикажано на екранот се снима. Затоа, бидете внимателни со лозинките, деталите за плаќање, пораките, фотографиите и аудиото и видеото."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Додека снимате апликација, може да се сними сѐ што се прикажува или пушта во таа апликација. Затоа, бидете внимателни со лозинките, деталите за плаќање, пораките, фотографиите и аудиото и видеото."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Снимај го екранот"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не можеше да се ажурира зададената вредност"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Зададени вредности"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Избрано"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Алатки"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Автоматски титлови"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Белешка"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Прикажувај икони за известувања со низок приоритет"</string>
     <string name="other" msgid="429768510980739978">"Друго"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"отстранување на плочката"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"додавање на плочката на крај"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Преместување на плочката"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Додавање плочка"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Преместување на <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додавање на позиција <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Позицијата е погрешна."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"изберете корисник"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Нема интернет"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Отворете ги поставките на <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Уредете го редоследот на поставките."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Мени на копчето за вклучување"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Страница <xliff:g id="ID_1">%1$d</xliff:g> од <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Заклучен екран"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(врската е прекината)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не се префрла. Допрете и обидете се пак."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Поврзете уред"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"За да ја емитувате сесијава, отворете ја апликацијата."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Сопри со емитување"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Достапни уреди за аудиоизлез."</string>
@@ -1468,33 +1486,28 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Оди на почетниот екран"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Прикажи ги неодамнешните апликации"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Обидете се повторно!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Повлечете налево или надесно со три прста на допирната подлога"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Одлично!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Го научивте движењето за враќање назад."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"За да се вратите назад со допирната подлога, повлечете налево или надесно со три прста"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Одете на почетниот екран"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Повлечете нагоре со три прсти на допирната подлога"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Одлично!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Го завршивте движењето за враќање на почетниот екран"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Повлечете нагоре со три прста на допирната подлога за да одите на почетниот екран"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Прикажи ги неодамнешните апликации"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Повлечете нагоре и задржете со три прста на допирната подлога"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Одлично!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Го завршивте движењето за прегледување на неодамнешните апликации."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Повлечете нагоре со три прста на допирната подлога и задржете за да ги видите неодамнешните апликации"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Прегледајте ги сите апликации"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Притиснете го копчето за дејство на тастатурата"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Браво!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Го завршивте движењето за прегледување на сите апликации"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
-    <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Анимација за упатство, кликнете за ја паузирате и да ја продолжите репродукцијата."</string>
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Притиснете го копчето за дејство на тастатурата за да ги видите сите апликации"</string>
+    <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Анимација за упатство, кликнете за да го паузирате и да го продолжите пуштањето."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Осветлување на тастатура"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Ниво %1$d од %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Контроли за домот"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 0f8417e..db3e91a 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ഒരു സ്ക്രീൻ റെക്കോർഡിംഗ് സെഷനായി നിലവിലുള്ള അറിയിപ്പ്"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"നിങ്ങളുടെ സ്ക്രീൻ റെക്കോർഡ് ചെയ്യണോ?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ഒരു ആപ്പ് റെക്കോർഡ് ചെയ്യുക"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"സ്ക്രീൻ പൂർണ്ണമായി റെക്കോർഡ് ചെയ്യുക"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"മുഴുവൻ സ്ക്രീനും റെക്കോർഡ് ചെയ്യുക: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"നിങ്ങളുടെ സ്ക്രീൻ പൂർണ്ണമായി റെക്കോർഡ് ചെയ്യുമ്പോൾ, സ്ക്രീനിൽ ദൃശ്യമാകുന്ന എല്ലാം റെക്കോർഡ് ചെയ്യപ്പെടും. അതിനാൽ പാസ്‍വേഡുകൾ, പേയ്‌മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, ഓഡിയോ, വീഡിയോ എന്നിവ പോലുള്ള കാര്യങ്ങൾ നൽകുമ്പോൾ സൂക്ഷിക്കുക."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"നിങ്ങളുടെ ആപ്പ് റെക്കോർഡ് ചെയ്യുമ്പോൾ, ആ ആപ്പിൽ കാണിക്കുന്നതോ പ്ലേ ചെയ്യുന്നതോ ആയ എല്ലാ കാര്യങ്ങളും റെക്കോർഡ് ചെയ്യപ്പെടും. അതിനാൽ പാസ്‍വേഡുകൾ, പേയ്‌മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, ഓഡിയോ, വീഡിയോ എന്നിവ പോലുള്ള കാര്യങ്ങൾ നൽകുമ്പോൾ സൂക്ഷിക്കുക."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"സ്ക്രീൻ റെക്കോർഡ് ചെയ്യുക"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"പ്രീസെറ്റ് അപ്ഡേറ്റ് ചെയ്യാനായില്ല"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"പ്രീസെറ്റ്"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"തിരഞ്ഞെടുത്തു"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ടൂളുകൾ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"തത്സമയ ക്യാപ്ഷൻ"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"കുറിപ്പ്"</string>
@@ -960,9 +976,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"പ്രാധാന്യം കുറഞ്ഞ അറിയിപ്പ് ചിഹ്‌നങ്ങൾ"</string>
     <string name="other" msgid="429768510980739978">"മറ്റുള്ളവ"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ടൈൽ നീക്കം ചെയ്യുക"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ടൈൽ, അവസാന ഭാഗത്ത് ചേർക്കുക"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"അവസാന ഭാഗത്ത് ടൈൽ ചേർക്കുക"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ടൈൽ നീക്കുക"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"ടൈൽ ചേർക്കുക"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"ഇഷ്ടമുള്ള ഭാഗത്ത് ടൈൽ ചേർക്കുക"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> എന്നതിലേക്ക് നീക്കുക"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> എന്ന സ്ഥാനത്തേക്ക് ചേർക്കുക"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"സ്ഥാനം അസാധുവാണ്."</string>
@@ -978,7 +994,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ഉപയോക്താവിനെ തിരഞ്ഞെടുക്കുക"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ഇന്റർനെറ്റ് ഇല്ല"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ക്രമീകരണം തുറക്കുക."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ക്രമീകരണ ക്രമം എഡിറ്റുചെയ്യുക."</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"ദ്രുത ക്രമീകരണത്തിന്റെ ക്രമം എഡിറ്റ് ചെയ്യുക."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"പവർ മെനു"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"പേജ് <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ലോക്ക് സ്‌ക്രീൻ"</string>
@@ -1209,7 +1225,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(വിച്ഛേദിച്ചു)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"മാറാനാകുന്നില്ല. വീണ്ടും ശ്രമിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"ഒരു ഉപകരണം കണക്റ്റ് ചെയ്യുക"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ഈ സെഷൻ കാസ്റ്റ് ചെയ്യാൻ, ആപ്പ് തുറക്കുക."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"അജ്ഞാതമായ ആപ്പ്"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"കാസ്റ്റ് ചെയ്യുന്നത് നിർത്തുക"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ഓഡിയോ ഔട്ട്‌പുട്ടിന് ലഭ്യമായ ഉപകരണങ്ങൾ."</string>
@@ -1468,32 +1483,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"ഹോമിലേക്ക് പോകുക"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"അടുത്തിടെയുള്ള ആപ്പുകൾ കാണുക"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"പൂർത്തിയായി"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"വീണ്ടും ശ്രമിക്കുക!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"മടങ്ങുക"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"ടച്ച്‌പാഡിൽ മൂന്ന് വിരലുകൾ കൊണ്ട് ഇടത്തേക്കോ വലത്തേക്കോ സ്വൈപ്പ് ചെയ്യുക"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"കൊള്ളാം!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"മടങ്ങുക ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"നിങ്ങളുടെ ടച്ച്പാഡ് ഉപയോഗിച്ച് തിരികെ പോകാൻ, മൂന്ന് വിരലുകൾ ഉപയോഗിച്ച് ഇടത്തോട്ടോ വലത്തോട്ടോ സ്വൈപ്പ് ചെയ്യുക"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"ഹോമിലേക്ക് പോകൂ"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"ടച്ച്‌പാഡിൽ മൂന്ന് വിരലുകൾ ഉപയോഗിച്ച് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"കൊള്ളാം!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"ഹോം ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"നിങ്ങളുടെ ഹോം സ്‌ക്രീനിലേക്ക് പോകാൻ ടച്ച്‌പാഡിൽ മൂന്ന് വിരലുകൾ ഉപയോഗിച്ച് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"അടുത്തിടെയുള്ള ആപ്പുകൾ കാണുക"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"നിങ്ങളുടെ ടച്ച്പാഡിൽ മൂന്ന് വിരലുകൾ കൊണ്ട് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്‌ത് പിടിക്കുക"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"കൊള്ളാം!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"അടുത്തിടെയുള്ള ആപ്പുകൾ കാണുക എന്ന ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"സമീപകാല ആപ്പുകൾ കാണുന്നതിന്, നിങ്ങളുടെ ടച്ച്പാഡിൽ മൂന്ന് വിരലുകൾ ഉപയോഗിച്ച് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്‌ത് പിടിക്കുക"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"എല്ലാ ആപ്പുകളും കാണുക"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"നിങ്ങളുടെ കീബോർഡിലെ ആക്ഷൻ കീ അമർത്തുക"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"അഭിനന്ദനങ്ങൾ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"\'എല്ലാ ആപ്പുകളും കാണുക\' ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"നിങ്ങളുടെ എല്ലാ ആപ്പുകളും കാണുന്നതിന് കീബോർഡിലെ ആക്ഷൻ കീ അമർത്തുക"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"ട്യൂട്ടോറിയൽ ആനിമേഷൻ, താൽക്കാലികമായി നിർത്താനും പ്ലേ പുനരാരംഭിക്കാനും ക്ലിക്ക് ചെയ്യുക."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"കീബോഡ് ബാക്ക്‌ലൈറ്റ്"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-ൽ %1$d-ാമത്തെ ലെവൽ"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 47a5468..75471ba 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Дэлгэц бичих горимын үргэлжилж буй мэдэгдэл"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Дэлгэцээ бичих үү?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Нэг аппыг бичих"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Бүтэн дэлгэцийг бичих"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Дэлгэцийг бүхэлд нь бичих: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Таныг бүтэн дэлгэцээ бичиж байхад дэлгэц дээр тань харуулж буй аливаа зүйлийг бичдэг. Тиймээс нууц үг, төлбөрийн дэлгэрэнгүй, мессеж, зураг, аудио, видео зэрэг зүйлд болгоомжтой хандаарай."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Таныг апп бичиж байхад тухайн аппад харуулж эсвэл тоглуулж буй аливаа зүйлийг бичдэг. Тиймээс нууц үг, төлбөрийн дэлгэрэнгүй, мессеж, зураг, аудио, видео зэрэг зүйлд болгоомжтой хандаарай."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Дэлгэцийг бичих"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Урьдчилсан тохируулгыг шинэчилж чадсангүй"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Урьдчилсан тохируулга"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Сонгосон"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Хэрэгсэл"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Шууд тайлбар"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Тэмдэглэл"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Бага ач холбогдолтой мэдэгдлийн дүрс тэмдгийг харуулах"</string>
     <string name="other" msgid="429768510980739978">"Бусад"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"хавтанг хасна уу"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"дуусгахын тулд хавтан нэмэх"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Хавтанг зөөх"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Хавтан нэмэх"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> руу зөөнө үү"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> байрлалд нэмнэ үү"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Байрлал буруу байна."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"хэрэглэгчийг сонгох"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Интернэт алга"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> тохиргоог нээнэ үү."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Тохиргооны дарааллыг өөрчилнө үү."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Асаах/унтраах цэс"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>-н <xliff:g id="ID_1">%1$d</xliff:g>-р хуудас"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Түгжээтэй дэлгэц"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(салсан)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Сэлгэх боломжгүй. Дахин оролдохын тулд товшино уу."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Төхөөрөмж холбох"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Энэ үйл явдлыг дамжуулахын тулд аппыг нээнэ үү."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Үл мэдэгдэх апп"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Дамжуулахыг зогсоох"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Аудио гаралт хийх боломжтой төхөөрөмжүүд."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Нүүр хуудас руу очих"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Саяхны аппуудыг харах"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Болсон"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Дахин оролдоно уу!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Буцах"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Мэдрэгч самбар дээрээ гурван хуруугаа ашиглан зүүн эсвэл баруун тийш шударна уу"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Янзтай!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Та буцах зангааг гүйцэтгэлээ."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Мэдрэгч самбараа буцааж ашиглахын тулд гурван хуруугаараа зүүн эсвэл баруун тийш шударна уу"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Үндсэн нүүр лүү очих"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Мэдрэгч самбар дээрээ гурван хуруугаараа дээш шударна уу"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Үнэхээр сайн ажиллалаа!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Та үндсэн нүүр лүү очих зангааг гүйцэтгэлээ"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Үндсэн нүүр лүүгээ очихын тулд мэдрэгч самбар дээрээ гурван хуруугаараа дээш шударна уу"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Саяхны аппуудыг харах"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Мэдрэгч самбар дээрээ гурван хуруугаа ашиглан дээш шудраад, удаан дарна уу"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Сайн байна!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Та саяхны аппуудыг харах зангааг гүйцэтгэсэн."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Саяхны аппуудыг харахын тулд мэдрэгч самбар дээрээ гурван хуруугаараа дээш шудраад, удаан дарна уу"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Бүх аппыг харах"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Гар дээрх тусгай товчлуурыг дарна уу"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Сайн байна!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Та бүх аппыг харах зангааг гүйцэтгэлээ"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Бүх аппаа харахын тулд гар дээрээ байх тусгай товчлуурыг дарна уу"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Зааврын анимаци, түр зогсоохын тулд товшиж, үргэлжлүүлэн тоглуулна уу."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Гарын арын гэрэл"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-с %1$d-р түвшин"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index b5c298b..bd6cb13 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रेकॉर्ड सत्रासाठी सुरू असलेली सूचना"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"तुमची स्क्रीन रेकॉर्ड करायची आहे का?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एक अ‍ॅप रेकॉर्ड करा"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"पूर्ण स्क्रीन रेकॉर्ड करा"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"संपूर्ण स्क्रीन रेकॉर्ड करा: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"तुम्ही तुमची पूर्ण स्क्रीन रेकॉर्ड करता, तेव्हा तुमच्या स्क्रीनवर दाखवलेली कोणतीही गोष्ट रेकॉर्ड केली जाते. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"तुम्ही अ‍ॅप रेकॉर्ड करता, तेव्हा त्या अ‍ॅपमध्ये दाखवलेली किंवा प्ले केलेली कोणतीही गोष्ट रेकॉर्ड केली जाते. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रीन रेकॉर्ड करा"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रीसेट अपडेट करता आले नाही"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"प्रीसेट"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"निवडला आहे"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टूल"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइव्ह कॅप्शन"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"टीप"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"कमी प्राधान्य सूचना आयकन दर्शवा"</string>
     <string name="other" msgid="429768510980739978">"अन्य"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"टाइल काढून टाका"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"टाइल शेवटच्या स्थानावर जोडा"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"टाइल हलवा"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"टाइल जोडा"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> यावर हलवा"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> स्थानावर जोडा"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"स्थान चुकीचे आहे."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"वापरकर्ता निवडा"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"इंटरनेट नाही"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> सेटिंग्ज उघडा."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"सेटिंग्जचा क्रम संपादित करा."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"पॉवर मेनू"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> पैकी <xliff:g id="ID_1">%1$d</xliff:g> पेज"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"लॉक स्‍क्रीन"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिस्कनेक्ट केलेले)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"स्विच करू शकत नाही. पुन्हा प्रयत्न करण्यासाठी टॅप करा."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"डिव्हाइस कनेक्ट करा"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"हे सेशन कास्ट करण्यासाठी, कृपया ॲप उघडा."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अज्ञात अ‍ॅप"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्ट करणे थांबवा"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ऑडिओ आउटपुटसाठी उपलब्ध डिव्हाइस."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"होमवर जा"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"अलीकडील अ‍ॅप्स पहा"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"पूर्ण झाले"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"पुन्हा प्रयत्न करा!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"मागे जा"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"तुमच्या टचपॅडवर तीन बोटांनी डावीकडे किंवा उजवीकडे स्‍वाइप करा"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"छान!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"तुम्ही गो बॅक जेश्चर पूर्ण केले."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"तुमचा टचपॅड वापरून परत जाण्यासाठी, तीन बोटांनी डावीकडे किंवा उजवीकडे स्वाइप करा"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"होमवर जा"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"तुमच्या टचपॅडवर तीन बोटांनी वर स्वाइप करा"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"उत्तम कामगिरी!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"तुम्ही गो होम जेश्चर पूर्ण केले आहे"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"तुमच्या होम स्क्रीनवर जाण्यासाठी तुमच्या टचपॅडवर तीन बोटांनी वर स्वाइप करा"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"अलीकडील अ‍ॅप्स पहा"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"तुमच्या टचपॅडवर तीन बोटांनी वर स्वाइप करून धरून ठेवा"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"उत्तम कामगिरी!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"तुम्ही अलीकडील ॲप्स पाहण्याचे जेश्चर पूर्ण केले आहे."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"अलीकडील अ‍ॅप्स पाहण्यासाठी, तुमच्या टचपॅडवर तीन बोटांनी वर स्वाइप करून धरून ठेवा"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"सर्व अ‍ॅप्स पहा"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"तुमच्या कीबोर्डवर अ‍ॅक्शन की प्रेस करा"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"खूप छान!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"तुम्ही ॲप्स पाहण्याचे जेश्चर पूर्ण केले आहे"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"तुमचे सर्व ॲप्स पाहण्यासाठी तुमच्या कीबोर्डवरील अ‍ॅक्शन की प्रेस करा"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"ट्यूटोरियल अ‍ॅनिमेशन थांबवण्यासाठी किंवा पुन्हा सुरू करण्यासाठी प्ले करा वर क्लिक करा."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"कीबोर्ड बॅकलाइट"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d पैकी %1$d पातळी"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 481f662..3af5957 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pemberitahuan breterusan untuk sesi rakaman skrin"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Rakam skrin anda?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Rakam satu apl"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Rakam seluruh skrin"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Rakam keseluruhan skrin: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Apabila anda merakam seluruh skrin anda, apa-apa sahaja yang dipaparkan pada skrin anda akan dirakam. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Apabila anda merakam apl, apa-apa sahaja yang dipaparkan atau dimainkan dalam apl tersebut akan dirakam. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Rakam skrin"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Tidak dapat mengemaskinikan pratetapan"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Pratetapan"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Dipilih"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alatan"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sari Kata Langsung"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
@@ -960,9 +976,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Tunjukkan ikon pemberitahuan keutamaan rendah"</string>
     <string name="other" msgid="429768510980739978">"Lain-lain"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"alih keluar jubin"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"tambahkan jubin pada bahagian hujung"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"tambahkan jubin pada kedudukan terakhir"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Alihkan jubin"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Tambahkan jubin"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Tambahkan jubin pada kedudukan yang dikehendaki"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Alih ke <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Tambahkan pada kedudukan <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Kedudukan tidak sah."</string>
@@ -978,7 +994,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"pilih pengguna"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Tiada Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Buka tetapan <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edit susunan tetapan."</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"Edit urutan Tetapan Pantas."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu kuasa"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Halaman <xliff:g id="ID_1">%1$d</xliff:g> daripada <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Kunci skrin"</string>
@@ -1209,7 +1225,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(diputuskan sambungan)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Tidak dapat menukar. Ketik untuk mencuba lagi."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Sambungkan peranti"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Untuk menghantar sesi ini, sila buka apl."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Apl yang tidak diketahui"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Berhenti menghantar"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Peranti tersedia untuk audio output."</string>
@@ -1468,32 +1483,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Akses laman utama"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Lihat apl terbaharu"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Selesai"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Cuba lagi!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kembali"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Leret ke kiri atau ke kanan menggunakan tiga jari pada pad sentuh"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bagus!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Anda telah melengkapkan gerak isyarat kembali."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Untuk kembali menggunakan pad sentuh anda, leret ke kiri atau ke kanan menggunakan tiga jari"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Akses laman utama"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Leret ke atas dengan tiga jari pada pad sentuh anda"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Bagus!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Anda telah melengkapkan gerak isyarat akses laman utama"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Leret ke atas dengan tiga jari pada pad sentuh anda untuk mengakses skrin utama anda"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Lihat apl terbaharu"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Leret ke atas dan tahan menggunakan tiga jari pada pad sentuh"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Syabas!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Anda telah melengkapkan gerak isyarat lihat apl terbaharu."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Untuk melihat apl terbaharu, leret ke atas dan tahan menggunakan tiga jari pada pad sentuh anda"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Lihat semua apl"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tekan kekunci tindakan pada papan kekunci anda"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Syabas!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Anda telah melengkapkan gerak isyarat lihat semua apl"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Tekan kekunci tindakan pada papan kekunci anda untuk melihat semua apl anda"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animasi tutorial, klik untuk menjeda dan menyambung semula main."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Cahaya latar papan kekunci"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Tahap %1$d daripada %2$d"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index bde5f57..a8a2eaa 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ဖန်သားပြင် ရိုက်ကူးသည့် စက်ရှင်အတွက် ဆက်တိုက်လာနေသော အကြောင်းကြားချက်"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ဖန်သားပြင်ကို ရိုက်ကူးမလား။"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"အက်ပ်တစ်ခုကို ရိုက်ကူးရန်"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ဖန်သားပြင်တစ်ခုလုံးကို ရိုက်ကူးရန်"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ဖန်သားပြင်တစ်ခုလုံးကို ရိုက်ကူးရန်- %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"သင့်ဖန်သားပြင်တစ်ခုလုံး ရိုက်ကူးနေချိန်တွင် ဖန်သားပြင်တွင် ပြထားသည့် အရာအားလုံးကို ရိုက်ကူးသည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"အက်ပ်ကို ရိုက်ကူးနေချိန်တွင် ယင်းအက်ပ်တွင် ပြထားသော (သို့) ဖွင့်ထားသော အရာအားလုံးကို ရိုက်ကူးသည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ဖန်သားပြင်ကို ရိုက်ကူးရန်"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"အသင့်သုံးကို အပ်ဒိတ်လုပ်၍မရပါ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ကြိုတင်သတ်မှတ်ချက်"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ရွေးထားသည်"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"တူးလ်များ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"တိုက်ရိုက်စာတန်း"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"မှတ်စု"</string>
@@ -707,7 +723,7 @@
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ခေါင်းလှုပ်ရှားမှု"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"ဖုန်းခေါ်သံမုဒ်သို့ ပြောင်းရန် တို့ပါ"</string>
     <string name="volume_ringer_mode" msgid="6867838048430807128">"အသံမြည်မုဒ်"</string>
-    <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>၊ ဖုန်းခေါ်သံမုဒ်သို့ ပြောင်းရန် တို့ပါ"</string>
+    <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>၊ ဖုန်းခေါ်သံမုဒ် ပြောင်းရန် တို့ပါ"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"အသံပိတ်ရန်"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"အသံဖွင့်ရန်"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"တုန်ခါမှု"</string>
@@ -880,7 +896,7 @@
     <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"တစ်ပြိုင်နက် များစွာလုပ်ခြင်း"</string>
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"အက်ပ်ကို ညာ၌ထားကာ မျက်နှာပြင် ခွဲ၍ပြသခြင်း သုံးရန်"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"အက်ပ်ကို ဘယ်၌ထားကာ မျက်နှာပြင် ခွဲ၍ပြသခြင်း သုံးရန်"</string>
-    <string name="system_multitasking_full_screen" msgid="4940465971687159429">"ဖန်သားပြင်အပြည့် ပြောင်းခြင်း"</string>
+    <string name="system_multitasking_full_screen" msgid="4940465971687159429">"ဖန်သားပြင်အပြည့် ပြောင်းရန်"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"မျက်နှာပြင်ခွဲ၍ပြသခြင်း သုံးစဉ် ညာ (သို့) အောက်ရှိအက်ပ်သို့ ပြောင်းရန်"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းသုံးစဉ် ဘယ် (သို့) အထက်ရှိအက်ပ်သို့ ပြောင်းရန်"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"မျက်နှာပြင် ခွဲ၍ပြသစဉ်- အက်ပ်တစ်ခုကို နောက်တစ်ခုနှင့် အစားထိုးရန်"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"အရေးမကြီးသော အကြောင်းကြားချက် သင်္ကေတများ ပြရန်"</string>
     <string name="other" msgid="429768510980739978">"အခြား"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"အကွက်ငယ်ကို ဖယ်ရှားရန်"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"အဆုံးတွင် အကွက်ငယ်ထည့်ရန်"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"အကွက်ငယ်ကို ရွှေ့ရန်"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"အကွက်ငယ်ကို ထည့်ရန်"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> သို့ ရွှေ့ရန်"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> အနေအထားသို့ ပေါင်းထည့်ရန်"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"နေရာ မမှန်ပါ။"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"အသုံးပြုသူရွေးရန်"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"အင်တာနက် မရှိပါ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ဆက်တင်များကို ဖွင့်ပါ။"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ဆက်တင်များ၏ အစီအစဉ်ကို တည်းဖြတ်ပါ။"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ပါဝါမီနူး"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"စာမျက်နှာ <xliff:g id="ID_2">%2$d</xliff:g> အနက်မှ စာမျက်နှာ <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"လော့ခ်မျက်နှာပြင်"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ချိတ်ဆက်မှု မရှိပါ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ပြောင်း၍ မရပါ။ ပြန်စမ်းကြည့်ရန် တို့ပါ။"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"စက်တစ်ခုနှင့် ချိတ်ဆက်ရန်"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"အက်ပ်ဖွင့်ပြီး ဤစက်ရှင်ကို ကာစ်လုပ်နိုင်သည်။"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"အမည်မသိ အက်ပ်"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ကာစ် ရပ်ရန်"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"အသံအထွက်အတွက် ရရှိနိုင်သောစက်များ။"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"ပင်မစာမျက်နှာသို့ သွားရန်"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"မကြာသေးမီကအက်ပ်များကို ကြည့်ရန်"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ပြီးပြီ"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ပြန်သွားရန်"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"သင့်တာ့ချ်ပက်တွင် လက်သုံးချောင်းဖြင့် ဘယ် (သို့) ညာသို့ ပွတ်ဆွဲပါ"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"ကောင်းပါသည်။"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"နောက်သို့လက်ဟန် အပြီးသတ်လိုက်ပါပြီ"</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"တာ့ချ်ပက်ပြန်သုံးရန် လက်သုံးချောင်းဖြင့် ဘယ်/ညာ ပွတ်ဆွဲပါ"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"ပင်မစာမျက်နှာသို့ သွားရန်"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"တာ့ချ်ပက်ပေါ်တွင် လက်သုံးချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပါ"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"တော်ပါပေသည်။"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"ပင်မစာမျက်နှာသို့သွားသည့် လက်ဟန် အပြီးသတ်လိုက်ပါပြီ"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"ပင်မစာမျက်နှာသို့ သွားရန် တာ့ချ်ပက်တွင် လက်သုံးချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပါ"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"မကြာသေးမီကအက်ပ်များကို ကြည့်ခြင်း"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"သင့်တာ့ချ်ပက်တွင် လက်သုံးချောင်းဖြင့် အပေါ်သို့ပွတ်ဆွဲပြီး ဖိထားပါ"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"တော်ပါပေသည်။"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"မကြာသေးမီကအက်ပ်များကို ကြည့်ခြင်းလက်ဟန် သင်ခန်းစာပြီးပါပြီ။"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"လတ်တလောအက်ပ်များကြည့်ရန် တာ့ချ်ပက်တွင် လက်သုံးချောင်းဖြင့် အပေါ်သို့ပွတ်ဆွဲပြီး ဖိထားပါ"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"အက်ပ်အားလုံးကို ကြည့်ခြင်း"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ကီးဘုတ်တွင် လုပ်ဆောင်ချက်ကီး နှိပ်ပါ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"အလွန်ကောင်းပါသည်။"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"အက်ပ်အားလုံးကို ကြည့်ခြင်းလက်ဟန် သင်ခန်းစာပြီးပါပြီ"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"အက်ပ်အားလုံးကြည့်ရန် ကီးဘုတ်ပေါ်ရှိ လုပ်ဆောင်ချက်ကီးကို နှိပ်ပါ"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"ရှင်းလင်းပို့ချချက် လှုပ်ရှားသက်ဝင်ပုံ၊ ခဏရပ်ပြီး ဆက်ဖွင့်ရန် နှိပ်ပါ။"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ကီးဘုတ်နောက်မီး"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"အဆင့် %2$d အနက် %1$d"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 9dd0f99..ae135cc 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Vedvarende varsel for et skjermopptak"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vil du ta opp skjermen?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Ta opp én app"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Ta opp hele skjermen"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Ta opp hele skjermen: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Når du tar opp hele skjermen, blir alt som vises på skjermen, tatt opp. Derfor bør du være forsiktig med for eksempel passord, betalingsopplysninger, meldinger, bilder, lyd og video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Når du tar opp en app, blir alt som vises eller spilles av i appen, tatt opp. Derfor bør du være forsiktig med for eksempel passord, betalingsopplysninger, meldinger, bilder, lyd og video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ta opp skjermen"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Kunne ikke oppdatere forhåndsinnstillingen"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forhåndsinnstilling"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valgt"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verktøy"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Direkteteksting"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Merknad"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Vis ikoner for varsler med lav prioritet"</string>
     <string name="other" msgid="429768510980739978">"Annet"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"fjerne infobrikken"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"legge til en infobrikke på slutten"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Flytt infobrikken"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Legg til en infobrikke"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Flytt til <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Legg til posisjonen <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posisjonen er ugyldig."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"velge en bruker"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Ingen internettilkobling"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Åpne <xliff:g id="ID_1">%s</xliff:g>-innstillingene."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Endre rekkefølgen på innstillingene."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Av/på-meny"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Side <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Låseskjerm"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(frakoblet)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan ikke bytte. Trykk for å prøve igjen."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Koble til en enhet"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"For å caste denne økten, åpne appen."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ukjent app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stopp castingen"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Tilgjengelige enheter for lydutgang."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Gå til startsiden"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Se nylige apper"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Ferdig"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Prøv på nytt."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Gå tilbake"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Sveip til venstre eller høyre med tre fingre på styreflaten"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bra!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Du har fullført bevegelsen for å gå tilbake."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"For å gå tilbake med styreflaten, sveip til venstre eller høyre med tre fingre"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Gå til startsiden"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Sveip opp med tre fingre på styreflaten"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Bra jobbet!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Du har fullført bevegelsen for å gå til startskjermen"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Sveip opp med tre fingre på styreflaten for å gå til startskjermen"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Se nylige apper"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Sveip opp og hold med tre fingre på styreflaten"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Bra jobbet!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Du har fullført bevegelsen for å se nylige apper."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"For å se nylige apper, sveip opp og hold med tre fingre på styreflaten"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Se alle apper"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Trykk på handlingstasten på tastaturet"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bra!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Du har fullført bevegelsen for å se alle apper"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Trykk på handlingstasten på tastaturet for å se alle appene dine"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Veiledningsanimasjon. Klikk for å sette avspillingen på pause og gjenoppta den."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Bakgrunnslys for tastatur"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivå %1$d av %2$d"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 968fd51..c701ebc 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -54,7 +54,7 @@
     <string name="usb_debugging_always" msgid="4003121804294739548">"यो कम्प्युटरबाट सधैँ अनुमति दिनुहोस्"</string>
     <string name="usb_debugging_allow" msgid="1722643858015321328">"अनुमति दिनुहोस्"</string>
     <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB डिबग गर्न अनुमति छैन"</string>
-    <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"हालैमा यस डिभाइसमा साइन इन भएका प्रयोगकर्ताले USB डिबगिङ सक्रिय गर्न सक्दैनन्। यो सुविधा प्रयोग गर्न कृपया खाताका एड्मिनका रूपमा साइन इन गर्नुहोस्।"</string>
+    <string name="usb_debugging_secondary_user_message" msgid="1888835696965417845">"हाल यस डिभाइसमा साइन इन भएका प्रयोगकर्ताले USB डिबगिङ सक्रिय गर्न सक्दैनन्। यो सुविधा प्रयोग गर्न कृपया खाताका एड्मिनका रूपमा साइन इन गर्नुहोस्।"</string>
     <string name="hdmi_cec_set_menu_language_title" msgid="1259765420091503742">"तपाईं सिस्टमको भाषा बदलेर <xliff:g id="LANGUAGE">%1$s</xliff:g> बनाउन चाहनुहुन्छ?"</string>
     <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"अर्को डिभाइसले सिस्टमको भाषा परिवर्तन गर्न अनुरोध गरेको छ"</string>
     <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"भाषा परिवर्तन गर्नुहोस्"</string>
@@ -65,7 +65,7 @@
     <string name="wifi_debugging_always" msgid="2968383799517975155">"यस नेटवर्कमा सधैँ अनुमति दिनुहोस्"</string>
     <string name="wifi_debugging_allow" msgid="4573224609684957886">"अनुमति दिनुहोस्"</string>
     <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"वायरलेस डिबगिङ सेवालाई अनुमति दिइएको छैन"</string>
-    <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"हालैमा यस डिभाइसमा साइन इन भएका प्रयोगकर्ताले USB डिबगिङ सक्रिय गर्न सक्दैनन्। यो सुविधा प्रयोग गर्न कृपया खाताका एड्मिनका रूपमा साइन इन गर्नुहोस्।"</string>
+    <string name="wifi_debugging_secondary_user_message" msgid="9085779370142222881">"हाल यस डिभाइसमा साइन इन भएका प्रयोगकर्ताले USB डिबगिङ अन गर्न सक्दैनन्। यो सुविधा प्रयोग गर्न कृपया खाताका एड्मिनका रूपमा साइन इन गर्नुहोस्।"</string>
     <string name="usb_contaminant_title" msgid="894052515034594113">"USB पोर्ट असक्षम पारियो"</string>
     <string name="usb_contaminant_message" msgid="7730476585174719805">"तपाईंको यन्त्रलाई तरल पदार्थ वा धुलोबाट जोगाउन यसको USB पोर्ट असक्षम पारिएको छ र यसले कुनै पनि सहायक उपकरणहरू पहिचान गर्ने छैन।\n\nउक्त USB पोर्ट फेरि प्रयोग गर्दा हुन्छ भने तपाईंलाई यसबारे सूचित गरिने छ।"</string>
     <string name="usb_port_enabled" msgid="531823867664717018">"चार्जर तथा सामानहरू पत्ता लगाउन सक्षम पारिएको USB पोर्ट"</string>
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"कुनै स्क्रिन रेकर्ड गर्ने सत्रका लागि चलिरहेको सूचना"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"तपाईंको स्क्रिन रेकर्ड गर्ने हो?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एउटा एप रेकर्ड गर्नुहोस्"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"पूरै स्क्रिन रेकर्ड गर्नुहोस्"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"सम्पूर्ण स्क्रिन रेकर्ड गर्नुहोस्: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"तपाईंले आफ्नो पूरै स्क्रिन रेकर्ड गरिरहेका बेला तपाईंको स्क्रिनमा देखाइने सबै सामग्री रेकर्ड गरिन्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"तपाईंले यो एप रेकर्ड गरिरहेका बेला यो एपमा देखाइने वा प्ले गरिने सबै सामग्री रेकर्ड गरिन्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रिन रेकर्ड गर्नुहोस्"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रिसेट अपडेट गर्न सकिएन"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"पूर्वनिर्धारित"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"चयन गरिएको छ"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टुल"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइभ क्याप्सन"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"नोट"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"कम प्राथमिकताका सूचना आइकनहरू देखाउनुहोस्"</string>
     <string name="other" msgid="429768510980739978">"अन्य"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"टाइल हटाउनुहोस्"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"टाइल अन्त्यमा हाल्नुहोस्"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"टाइल सार्नुहोस्"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"टाइल हाल्नुहोस्"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"टाइल सारेर <xliff:g id="POSITION">%1$d</xliff:g> मा लैजानुहोस्"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"टाइल यो अवस्था <xliff:g id="POSITION">%1$d</xliff:g> मा हाल्नुहोस्"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"पोजिसन अवैध छ।"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"प्रयोगकर्ता छान्नुहोस्"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"इन्टरनेट छैन"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> सम्बन्धी सेटिङहरूलाई खोल्नुहोस्।"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"सेटिङहरूको क्रमलाई सम्पादन गर्नुहोस्।"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"पावर मेनु"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> मध्ये पृष्ठ <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"लक स्क्रिन"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(डिस्कनेक्ट गरिएको छ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"बदल्न सकिएन। फेरि प्रयास गर्न ट्याप गर्नुहोस्।"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"कुनै डिभाइस कनेक्ट गर्नुहोस्"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"यो सत्र कास्ट गर्न चाहनुहुन्छ भने कृपया एप खोल्नुहोस्।"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अज्ञात एप"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्ट गर्न छाड्नुहोस्"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"अडियो आउटपुटका लागि उपलब्ध डिभाइसहरू।"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"होम स्क्रिनमा जानुहोस्"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"हालसालै चलाइएका एपहरू हेर्नुहोस्"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"सम्पन्न भयो"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"फेरि प्रयास गर्नुहोस्!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"पछाडि जानुहोस्"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"तीन वटा औँला प्रयोग गरी टचप्याडमा बायाँ वा दायाँतिर स्वाइप गर्नुहोस्"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"राम्रो!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"तपाईंले जेस्चर प्रयोग गरी पछाडि जाने तरिका सिक्नुभएको छ।"</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"टचप्याड प्रयोग गरी पछाडि जान तीन औँला प्रयोग गरी बायाँ वा दायाँतिर स्वाइप गर्नुहोस्"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"होमपेजमा जानुहोस्"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"टचप्याडमा तीन वटा औँलाले माथितिर स्वाइप गर्नुहोस्"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"अद्भुत!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"तपाईंले \"होम स्क्रिनमा जानुहोस्\" नामक जेस्चर प्रयोग गर्ने तरिका सिक्नुभयो"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"होम स्क्रिनमा जान टचप्याडमा तीन औँलाले माथितिर स्वाइप गर्नुहोस्"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"हालसालै चलाइएका एपहरू हेर्नुहोस्"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"तीन वटा औँला प्रयोग गरी टचप्याडमा माथितिर स्वाइप गर्नुहोस् र होल्ड गर्नुहोस्"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"अद्भुत!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"तपाईंले जेस्चर प्रयोग गरी हालसालै चलाइएका एपहरू हेर्ने तरिका सिक्नुभएको छ।"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"हालसालैका एपहरू हेर्न तीन औँला प्रयोग गरी टचप्याडमा माथितिर स्वाइप गर्नुहोस् र होल्ड गर्नुहोस्"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"सबै एपहरू हेर्नुहोस्"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"आफ्नो किबोर्डमा भएको एक्सन की थिच्नुहोस्"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"स्याबास!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"तपाईंले जेस्चर प्रयोग गरी सबै एपहरू हेर्ने तरिका सिक्नुभएको छ"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"आफ्ना सबै एपहरू हेर्न आफ्नो किबोर्डमा भएको एक्सन की थिच्नुहोस्"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"ट्युटोरियलको एनिमेसन, पज वा सुचारु गर्न क्लिक गर्नुहोस्।"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"किबोर्ड ब्याकलाइट"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d मध्ये %1$d औँ स्तर"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index adc157b..55b701e 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Doorlopende melding voor een schermopname-sessie"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Je scherm opnemen?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Eén app opnemen"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Hele scherm opnemen"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Hele scherm opnemen: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Als je je hele scherm opneemt, wordt alles opgenomen wat op je scherm wordt getoond. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Als je een app opneemt, wordt alles opgenomen wat wordt getoond of afgespeeld in die app. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Scherm opnemen"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Kan voorinstelling niet updaten"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voorinstelling"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Geselecteerd"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live ondertiteling"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notitie"</string>
@@ -960,9 +976,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Iconen voor meldingen met lage prioriteit tonen"</string>
     <string name="other" msgid="429768510980739978">"Overig"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"tegel verwijderen"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"tegel toevoegen aan einde"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"tegel toevoegen op de laatste positie"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Tegel verplaatsen"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Tegel toevoegen"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Tegel toevoegen op gewenste positie"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Verplaatsen naar <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Toevoegen aan positie <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Positie ongeldig."</string>
@@ -978,7 +994,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"gebruiker kiezen"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Geen internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g>-instellingen openen."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Volgorde van instellingen bewerken."</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"Volgorde van Snelle instellingen bewerken."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Aan/uit-menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> van <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Vergrendelscherm"</string>
@@ -1209,7 +1225,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(verbinding verbroken)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Kan niet schakelen. Tik om het opnieuw te proberen."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Apparaat koppelen"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Als je deze sessie wilt casten, open je de app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Casten stoppen"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Beschikbare apparaten voor audio-uitvoer."</string>
@@ -1468,32 +1483,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Naar startscherm"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Recente apps bekijken"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Klaar"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Probeer het nog eens."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Terug"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Swipe met 3 vingers naar links of rechts op de touchpad"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Goed zo!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Je weet nu hoe je het gebaar voor terug maakt."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Als je met de touchpad wilt teruggaan, swipe je met 3 vingers naar links of rechts"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Naar startscherm"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Swipe met 3 vingers omhoog op de touchpad"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Goed gedaan!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Je weet nu hoe je het gebaar Naar startscherm maakt"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Swipe met 3 vingers omhoog op de touchpad om naar het startscherm te gaan"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Recente apps bekijken"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Swipe met 3 vingers omhoog en houd vast op de touchpad"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Goed gedaan!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Je weet nu hoe je het gebaar Recente apps bekijken maakt."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Als je recente apps wilt bekijken, swipe je met 3 vingers omhoog op de touchpad en houd je vast"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Alle apps bekijken"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Druk op de actietoets op het toetsenbord"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Goed gedaan!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Je weet nu hoe je het gebaar Alle apps bekijken maakt"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Druk op de actietoets op je toetsenbord om al je apps te bekijken"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Tutorial-animatie, klik om het afspelen te onderbreken en te hervatten."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Achtergrondverlichting van toetsenbord"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d van %2$d"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 12a13ff..1ac2170 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ଏକ ସ୍କ୍ରି‍ନ୍‍ ରେକର୍ଡ୍‍ ସେସନ୍‍ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ଆପଣଙ୍କ ସ୍କ୍ରିନକୁ ରେକର୍ଡ କରିବେ?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ଗୋଟିଏ ଆପ ରେକର୍ଡ କରନ୍ତୁ"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ ରେକର୍ଡ କରନ୍ତୁ"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ ରେକର୍ଡ କରନ୍ତୁ: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ଆପଣ ଆପଣଙ୍କର ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ ରେକର୍ଡ କରିବା ସମୟରେ, ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଦେଖାଯାଉଥିବା ସବୁକିଛି ରେକର୍ଡ ହୋଇଥାଏ। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ଆପଣ ଏକ ଆପ ରେକର୍ଡ କରିବା ସମୟରେ, ସେହି ଆପରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ପ୍ଲେ ହେଉଥିବା ସବୁକିଛି ରେକର୍ଡ ହୋଇଥାଏ। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ସ୍କ୍ରିନ ରେକର୍ଡ କରନ୍ତୁ"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ପ୍ରିସେଟକୁ ଅପଡେଟ କରାଯାଇପାରିଲା ନାହିଁ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ପ୍ରିସେଟ"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ଚୟନ କରାଯାଇଛି"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ଟୁଲ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ଲାଇଭ କେପ୍ସନ"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"ନୋଟ"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"କମ୍‍-ଅଗ୍ରାଧିକାର ବିଜ୍ଞପ୍ତି ଆଇକନ୍‍ ଦେଖାନ୍ତୁ"</string>
     <string name="other" msgid="429768510980739978">"ଅନ୍ୟ"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ଟାଇଲ୍ କାଢ଼ି ଦିଅନ୍ତୁ"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ଶେଷରେ ଟାଇଲ୍ ଯୋଗ କରନ୍ତୁ"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ଟାଇଲ୍ ମୁଭ୍ କରନ୍ତୁ"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"ଟାଇଲ୍ ଯୋଗ କରନ୍ତୁ"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g>କୁ ମୁଭ୍ କରନ୍ତୁ"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ଅବସ୍ଥିତିରେ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ଅବସ୍ଥିତି ଅବୈଧ ଅଟେ।"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ୟୁଜର ବାଛନ୍ତୁ"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"କୌଣସି ଇଣ୍ଟରନେଟ୍‌ କନେକ୍ସନ୍ ନାହିଁ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ।"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ସେଟିଂସର କ୍ରମ ଏଡିଟ କରନ୍ତୁ।"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ପାୱାର ମେନୁ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ପୃଷ୍ଠା <xliff:g id="ID_1">%1$d</xliff:g> ମୋଟ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"ଲକ ସ୍କ୍ରିନ"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ବିଚ୍ଛିନ୍ନ କରାଯାଇଛି)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ସ୍ୱିଚ କରାଯାଇପାରିବ ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"ଗୋଟିଏ ଡିଭାଇସ କନେକ୍ଟ କରନ୍ତୁ"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ଏହି ସେସନକୁ କାଷ୍ଟ କରିବା ପାଇଁ, ଦୟାକରି ଆପ ଖୋଲନ୍ତୁ।"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ଅଜଣା ଆପ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"କାଷ୍ଟ କରିବା ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ଅଡିଓ ଆଉଟପୁଟ ପାଇଁ ଉପଲବ୍ଧ ଡିଭାଇସଗୁଡ଼ିକ।"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"ହୋମକୁ ଯାଆନ୍ତୁ"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"ବର୍ତ୍ତମାନର ଆପ୍ସ ଭ୍ୟୁ କରନ୍ତୁ"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ହୋଇଗଲା"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ପଛକୁ ଫେରନ୍ତୁ"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"ଆପଣଙ୍କ ଟଚପେଡରେ ତିନୋଟି ଆଙ୍ଗୁଠି ବ୍ୟବହାର କରି ବାମ କିମ୍ବା ଡାହାଣକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"ବଢ଼ିଆ!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"ଆପଣ \'ପଛକୁ ଫେରନ୍ତୁ\' ଜେଶ୍ଚର ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"ଆପଣଙ୍କ ଟଚପେଡକୁ ବ୍ୟବହାର କରି ପଛକୁ ଫେରିବା ପାଇଁ ତିନୋଟି ଆଙ୍ଗୁଠି ବ୍ୟବହାର କରି ବାମ କିମ୍ବା ଡାହାଣକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"ହୋମକୁ ଯାଆନ୍ତୁ"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"ଆପଣଙ୍କ ଟଚପେଡରେ ତିନୋଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"ବଢ଼ିଆ କାମ!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"ଆପଣ \'ହୋମକୁ ଯାଆନ୍ତୁ\' ଜେଶ୍ଚର ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"ଆପଣଙ୍କର ହୋମ ସ୍କ୍ରିନକୁ ଯିବା ପାଇଁ ଆପଣଙ୍କ ଟଚପେଡରେ ତିନୋଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"ବର୍ତ୍ତମାନର ଆପ୍ସକୁ ଭ୍ୟୁ କରନ୍ତୁ"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"ଆପଣଙ୍କ ଟଚପେଡରେ ତିନୋଟି ଆଙ୍ଗୁଠିକୁ ବ୍ୟବହାର କରି ଉପରକୁ ସ୍ୱାଇପ କରି ଧରି ରଖନ୍ତୁ"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"ବଢ଼ିଆ କାମ!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ଆପଣ ବର୍ତ୍ତମାନର ଆପ୍ସ ଜେଶ୍ଚରକୁ ଭ୍ୟୁ କରିବା ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"ବର୍ତ୍ତମାନର ଆପ୍ସ ଭ୍ୟୁ କରିବାକୁ, ଆପଣଙ୍କ ଟଚପେଡରେ ତିନୋଟି ଆଙ୍ଗୁଠି ବ୍ୟବହାର କରି ଉପରକୁ ସ୍ୱାଇପ କରି ଧରି ରଖନ୍ତୁ"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"ସବୁ ଆପ ଭ୍ୟୁ କରନ୍ତୁ"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ଆପଣଙ୍କର କୀବୋର୍ଡରେ ଆକ୍ସନ କୀ\'କୁ ଦବାନ୍ତୁ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ବହୁତ ବଢ଼ିଆ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ଆପଣ ସମସ୍ତ ଆପ୍ସ ଜେଶ୍ଚରକୁ ଭ୍ୟୁ କରିବା ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"ଆପଣଙ୍କ ସମସ୍ତ ଆପ୍ସକୁ ଭ୍ୟୁ କରିବା ପାଇଁ ଆପଣଙ୍କର କୀବୋର୍ଡରେ ଆକ୍ସନ କୀ\'କୁ ଦବାନ୍ତୁ"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"ଟ୍ୟୁଟୋରିଆଲ ଆନିମେସନ, ପ୍ଲେ କରିବା ବିରତ କରି ପୁଣି ଆରମ୍ଭ କରିବାକୁ କ୍ଲିକ କରନ୍ତୁ।"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"କୀବୋର୍ଡ ବେକଲାଇଟ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dରୁ %1$d ନମ୍ବର ଲେଭେଲ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index feaae0e..6eda17a 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ਕਿਸੇ ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਸੈਸ਼ਨ ਲਈ ਚੱਲ ਰਹੀ ਸੂਚਨਾ"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ਕੀ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ ਨੂੰ ਰਿਕਾਰਡ ਕਰਨਾ ਹੈ?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ਇੱਕ ਐਪ ਨੂੰ ਰਿਕਾਰਡ ਕਰੋ"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਰਿਕਾਰਡ ਕਰੋ"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ਸਾਰੀ ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਕਰੋ: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ਜਦੋਂ ਤੁਸੀਂ ਆਪਣੀ ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਰਿਕਾਰਡ ਕਰ ਰਹੇ ਹੁੰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਖਾਈ ਜਾ ਰਹੀ ਹਰ ਚੀਜ਼ ਨੂੰ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਨਾਲ ਹੀ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਵਾਸਤੇ ਸਾਵਧਾਨ ਰਹੋ।"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ਜਦੋਂ ਤੁਸੀਂ ਕਿਸੇ ਐਪ ਨੂੰ ਰਿਕਾਰਡ ਕਰ ਰਹੇ ਹੁੰਦੇ ਹੋ, ਤਾਂ ਉਸ ਐਪ ਵਿੱਚ ਦਿਖਾਈ ਜਾਂ ਚਲਾਈ ਜਾ ਰਹੀ ਹਰ ਚੀਜ਼ ਨੂੰ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਵਾਸਤੇ ਸਾਵਧਾਨ ਰਹੋ।"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਕਰੋ"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ਪ੍ਰੀਸੈੱਟ ਨੂੰ ਅੱਪਡੇਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ਪ੍ਰੀਸੈੱਟ"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ਚੁਣਿਆ ਗਿਆ"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ਟੂਲ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ਲਾਈਵ ਸੁਰਖੀਆਂ"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"ਨੋਟ-ਕਥਨ"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"ਘੱਟ ਤਰਜੀਹ ਵਾਲੇ ਸੂਚਨਾ ਪ੍ਰਤੀਕਾਂ ਨੂੰ ਦਿਖਾਓ"</string>
     <string name="other" msgid="429768510980739978">"ਹੋਰ"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ਟਾਇਲ ਹਟਾਓ"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ਟਾਇਲ ਨੂੰ ਅੰਤ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ਟਾਇਲ ਨੂੰ ਲਿਜਾਓ"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"ਟਾਇਲ ਸ਼ਾਮਲ ਕਰੋ"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> \'ਤੇ ਲਿਜਾਓ"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ਸਥਾਨ \'ਤੇ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ਮੌਜੂਦਾ ਥਾਂ ਅਵੈਧ ਹੈ।"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"ਵਰਤੋਂਕਾਰ ਚੁਣੋ"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ਇੰਟਰਨੈੱਟ ਨਹੀਂ।"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ।"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ਸੈਟਿੰਗਾਂ ਦੇ ਕ੍ਰਮ ਦਾ ਸੰਪਾਦਨ ਕਰੋ।"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ਪਾਵਰ ਮੀਨੂ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ਦਾ <xliff:g id="ID_1">%1$d</xliff:g> ਪੰਨਾ"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">" ਲਾਕ  ਸਕ੍ਰੀਨ"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ਡਿਸਕਨੈਕਟ ਹੈ)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"ਡੀਵਾਈਸ ਕਨੈਕਟ ਕਰੋ"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ਇਸ ਸੈਸ਼ਨ ਨੂੰ ਕਾਸਟ ਕਰਨ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਐਪ ਖੋਲ੍ਹੋ।"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ਅਗਿਆਤ ਐਪ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰੋ"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ਆਡੀਓ ਆਊਟਪੁੱਟ ਲਈ ਉਪਲਬਧ ਡੀਵਾਈਸ।"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"ਹੋਮ \'ਤੇ ਜਾਓ"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"ਹਾਲੀਆ ਐਪਾਂ ਦੇਖੋ"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ਹੋ ਗਿਆ"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ਵਾਪਸ ਜਾਓ"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"ਆਪਣੇ ਟੱਚਪੈਡ \'ਤੇ ਤਿੰਨ ਉਂਗਲਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਖੱਬੇ ਜਾਂ ਸੱਜੇ ਪਾਸੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"ਵਧੀਆ!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"ਤੁਸੀਂ \'ਵਾਪਸ ਜਾਓ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ।"</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"ਆਪਣੇ ਟੱਚਪੈਡ ਨੂੰ ਵਰਤ ਕੇ ਵਾਪਸ ਜਾਣ ਲਈ, ਤਿੰਨ ਉਂਗਲਾਂ ਵਰਤ ਕੇ ਖੱਬੇ ਜਾਂ ਸੱਜੇ ਪਾਸੇ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"ਹੋਮ \'ਤੇ ਜਾਓ"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"ਆਪਣੇ ਟੱਚਪੈਡ \'ਤੇ ਤਿੰਨ ਉਂਗਲਾਂ ਨਾਲ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"ਬਹੁਤ ਵਧੀਆ!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"ਤੁਸੀਂ \'ਹੋਮ \'ਤੇ ਜਾਓ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"ਆਪਣੀ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਜਾਣ ਲਈ ਆਪਣੇ ਟੱਚਪੈਡ \'ਤੇ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"ਹਾਲੀਆ ਐਪਾਂ ਦੇਖੋ"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"ਆਪਣੇ ਟੱਚਪੈਡ \'ਤੇ ਤਿੰਨ ਉਂਗਲਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰ ਕੇ ਦਬਾਈ ਰੱਖੋ"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"ਬਹੁਤ ਵਧੀਆ!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ਤੁਸੀਂ \'ਹਾਲੀਆ ਐਪਾਂ ਦੇਖੋ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ ਹੈ।"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"ਹਾਲੀਆ ਐਪਾਂ ਦੇਖਣ ਲਈ, ਆਪਣੇ ਟੱਚਪੈਡ \'ਤੇ ਤਿੰਨ ਉਂਗਲਾਂ ਵਰਤ ਕੇ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਰੋਕ ਕੇ ਰੱਖੋ"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"ਸਾਰੀਆਂ ਐਪਾਂ ਦੇਖੋ"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ਆਪਣੇ ਕੀ-ਬੋਰਡ \'ਤੇ ਕਾਰਵਾਈ ਕੁੰਜੀ ਨੂੰ ਦਬਾਓ"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"ਬਹੁਤ ਵਧੀਆ!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ਤੁਸੀਂ \'ਸਾਰੀਆਂ ਐਪਾਂ ਦੇਖੋ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ ਹੈ"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"ਆਪਣੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਦੇਖਣ ਲਈ ਆਪਣੇ ਕੀ-ਬੋਰਡ \'ਤੇ ਕਾਰਵਾਈ ਕੁੰਜੀ ਨੂੰ ਦਬਾਓ"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"ਟਿਊਟੋਰੀਅਲ ਐਨੀਮੇਸ਼ਨ, ਰੋਕਣ ਅਤੇ ਮੁੜ-ਚਾਲੂ ਕਰਨ ਲਈ ਕਲਿੱਕ ਕਰੋ।"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ਕੀ-ਬੋਰਡ ਬੈਕਲਾਈਟ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ਵਿੱਚੋਂ %1$d ਪੱਧਰ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index bd7496d..82e3f67 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Stałe powiadomienie o sesji rejestrowania zawartości ekranu"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Nagrywać ekran?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Nagrywaj jedną aplikację"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Nagrywaj cały ekran"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Nagraj cały ekran: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kiedy nagrywasz cały ekran, nagrane zostanie wszystko, co jest na nim widoczne. Dlatego uważaj na hasła, dane do płatności, wiadomości, zdjęcia, nagrania audio czy filmy."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kiedy nagrywasz aplikację, wszystko, co jest w niej wyświetlane lub odtwarzane, zostaje nagrane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Nagrywaj ekran"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nie udało się zaktualizować gotowego ustawienia"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Gotowe ustawienie"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Wybrano"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Narzędzia"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Napisy na żywo"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notatka"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Pokazuj ikony powiadomień o niskim priorytecie"</string>
     <string name="other" msgid="429768510980739978">"Inne"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"usunąć kartę"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"dodać kartę na końcu"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Przenieś kartę"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Dodaj kartę"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Przenieś do pozycji <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodaj w pozycji <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nieprawidłowa pozycja."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"wybrać użytkownika"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Brak internetu"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otwórz ustawienia: <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Edytuj kolejność ustawień."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu zasilania"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Strona <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekran blokady"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odłączono)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nie można przełączyć. Spróbuj ponownie."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Połącz urządzenie"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Aby przesłać tę sesję, otwórz aplikację."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nieznana aplikacja"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zatrzymaj przesyłanie"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostępne urządzenia do odtwarzania dźwięku."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Otwórz stronę główną"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Wyświetlanie ostatnich aplikacji"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gotowe"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Spróbuj jeszcze raz"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Wróć"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Przesuń 3 palcami w prawo lub w lewo na touchpadzie"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Super!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Gest przejścia wstecz został opanowany."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Aby przejść wstecz przy użyciu touchpada, przesuń trzema palcami w lewo lub w prawo"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Otwórz stronę główną"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Przesuń 3 palcami w górę na touchpadzie"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Dobra robota!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Gest przechodzenia na ekran główny został opanowany"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Aby przejść na ekran główny, przesuń 3 palcami w górę na touchpadzie"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Wyświetlanie ostatnich aplikacji"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Przesuń w górę za pomocą 3 palców na touchpadzie i przytrzymaj"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Brawo!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Znasz już gest wyświetlania ostatnio używanych aplikacji."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Aby wyświetlić ostatnie aplikacje, przesuń 3 palcami w górę na touchpadzie i przytrzymaj"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Wyświetl wszystkie aplikacje"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Naciśnij klawisz działania na klawiaturze"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Brawo!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Znasz już gest wyświetlania wszystkich aplikacji"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Aby wyświetlić wszystkie swoje aplikacje, naciśnij klawisz działania na klawiaturze"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animacja z samouczkiem. Kliknij, aby wstrzymać lub wznowić odtwarzanie."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podświetlenie klawiatury"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Poziom %1$d z %2$d"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index b2db120..4ebc7ae 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Gravar a tela?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Gravar um app"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gravar a tela toda"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Gravar a tela toda: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quando você grava a tela toda, tudo o que aparece nela é registrado. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quando você grava um app, todas as informações visíveis ou abertas nele ficam registradas. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Gravar a tela"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Legenda instantânea"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Observação"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar ícones de notificações de baixa prioridade"</string>
     <string name="other" msgid="429768510980739978">"Outros"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"remover o bloco"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"adicionar o bloco ao final"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mover bloco"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Adicionar bloco"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mover para <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adicionar à posição <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posição inválida."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"escolher o usuário"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Sem Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Abrir configurações de <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editar ordem das configurações."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu liga/desliga"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Tela de bloqueio"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(sem conexão)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não foi possível mudar. Toque para tentar novamente."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Conectar dispositivo"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Abra o app para transmitir esta sessão."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecido"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos disponíveis para saída de áudio."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Ir para a página inicial"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Ver os apps recentes"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Concluído"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Tente de novo"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Voltar"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Deslize para a esquerda ou direita com 3 dedos no touchpad"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Legal!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Você concluiu o gesto para voltar."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Para voltar usando o touchpad, deslize para a esquerda ou direita com três dedos"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Ir para a página inicial"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Deslize para cima com 3 dedos no touchpad"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Muito bem!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Você concluiu o gesto para acessar a tela inicial"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Deslize para cima com três dedos no touchpad para acessar a tela inicial"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Ver os apps recentes"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize para cima com 3 dedos e mantenha"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Muito bem!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Você concluiu o gesto para ver os apps recentes."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Se quiser ver os apps recentes, deslize para cima e pressione o touchpad com três dedos"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todos os apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pressione a tecla de ação no teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Muito bem!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Você concluiu o gesto para ver todos os apps"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Pressione a tecla de ação no teclado para ver todos os apps"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animação do tutorial. Clique para pausar ou retomar a reprodução."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz de fundo do teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index dcc8f02..2b49139 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação persistente de uma sessão de gravação de ecrã"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Gravar o ecrã?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Gravar uma app"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gravar o ecrã inteiro"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Gravar o ecrã inteiro: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quando está a gravar o ecrã inteiro, tudo o que é apresentado no ecrã é gravado. Por isso, tenha cuidado com, por exemplo, palavras-passe, detalhes de pagamento, mensagens, fotos, áudio e vídeo."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quando está a gravar uma app, tudo o que é apresentado ou reproduzido nessa app é gravado. Por isso, tenha cuidado com, por exemplo, palavras-passe, detalhes de pagamento, mensagens, fotos, áudio e vídeo."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Gravar ecrã"</string>
@@ -415,6 +417,13 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
+    <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ambiente"</string>
+    <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Esquerda"</string>
+    <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Direita"</string>
+    <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Expandir para controlos separados do lado direito e esquerdo"</string>
+    <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Reduzir para controlo unificado"</string>
+    <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Desativar som do ambiente"</string>
+    <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Reativar som do ambiente"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Legendas instantâneas"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
@@ -960,9 +969,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar ícones de notificações de prioridade baixa"</string>
     <string name="other" msgid="429768510980739978">"Outro"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"remover o cartão"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"adicionar o cartão ao final"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"adicionar o mosaico à última posição"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mover cartão"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Adicionar cartão"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Adicionar mosaico à posição pretendida"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mova para <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adicione à posição <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posição inválida."</string>
@@ -978,7 +987,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"escolher o utilizador"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Sem Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Abrir as definições de <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editar a ordem das definições."</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"Editar ordem das Definições rápidas."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu ligar/desligar"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ecrã de bloqueio"</string>
@@ -1209,7 +1218,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desligado)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não é possível mudar. Toque para tentar novamente."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Ligar um dispositivo"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para transmitir esta sessão, abra a app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecida"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos disponíveis para a saída de áudio."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index b2db120..4ebc7ae 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Gravar a tela?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Gravar um app"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gravar a tela toda"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Gravar a tela toda: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quando você grava a tela toda, tudo o que aparece nela é registrado. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quando você grava um app, todas as informações visíveis ou abertas nele ficam registradas. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Gravar a tela"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Legenda instantânea"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Observação"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar ícones de notificações de baixa prioridade"</string>
     <string name="other" msgid="429768510980739978">"Outros"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"remover o bloco"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"adicionar o bloco ao final"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mover bloco"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Adicionar bloco"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mover para <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adicionar à posição <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posição inválida."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"escolher o usuário"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Sem Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Abrir configurações de <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editar ordem das configurações."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu liga/desliga"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Tela de bloqueio"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(sem conexão)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não foi possível mudar. Toque para tentar novamente."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Conectar dispositivo"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Abra o app para transmitir esta sessão."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecido"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispositivos disponíveis para saída de áudio."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Ir para a página inicial"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Ver os apps recentes"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Concluído"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Tente de novo"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Voltar"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Deslize para a esquerda ou direita com 3 dedos no touchpad"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Legal!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Você concluiu o gesto para voltar."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Para voltar usando o touchpad, deslize para a esquerda ou direita com três dedos"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Ir para a página inicial"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Deslize para cima com 3 dedos no touchpad"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Muito bem!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Você concluiu o gesto para acessar a tela inicial"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Deslize para cima com três dedos no touchpad para acessar a tela inicial"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Ver os apps recentes"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Deslize para cima com 3 dedos e mantenha"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Muito bem!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Você concluiu o gesto para ver os apps recentes."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Se quiser ver os apps recentes, deslize para cima e pressione o touchpad com três dedos"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ver todos os apps"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pressione a tecla de ação no teclado"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Muito bem!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Você concluiu o gesto para ver todos os apps"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Pressione a tecla de ação no teclado para ver todos os apps"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animação do tutorial. Clique para pausar ou retomar a reprodução."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz de fundo do teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 7664145..6f49a80 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificare în curs pentru o sesiune de înregistrare a ecranului"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Înregistrezi ecranul?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Înregistrează o aplicație"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Înregistrează tot ecranul"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Înregistrează tot ecranul: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Când înregistrezi întregul ecran, se înregistrează tot ce apare pe ecran. Prin urmare, ai grijă cu parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Când înregistrezi o aplicație, se înregistrează tot ce se afișează sau se redă în aplicație. Prin urmare, ai grijă cu parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Înregistrează ecranul"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nu s-a putut actualiza presetarea"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Presetare"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selectat"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Instrumente"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitrări live"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notă"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Afișează pictogramele de notificare cu prioritate redusă"</string>
     <string name="other" msgid="429768510980739978">"Altele"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"elimină cardul"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"adaugă cardul la sfârșit"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mută cardul"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Adaugă un card"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mută pe poziția <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adaugă pe poziția <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Poziție nevalidă."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"alege utilizatorul"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Fără conexiune la internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Deschide setările <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Editează ordinea setărilor."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meniul de pornire"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> din <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ecran de blocare"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(deconectat)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nu se poate comuta. Atinge pentru a încerca din nou."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Conectează un dispozitiv"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pentru a proiecta această sesiune, deschide aplicația."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicație necunoscută"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Nu mai proiecta"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dispozitive disponibile pentru ieșire audio."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Înapoi la pagina de pornire"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Vezi aplicațiile recente"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Gata"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Încearcă din nou!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Înapoi"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Glisează la stânga sau la dreapta cu trei degete pe touchpad"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bravo!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Ai finalizat gestul Înapoi."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Pentru a reveni folosind touchpadul, glisează la stânga sau la dreapta cu trei degete"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Înapoi la pagina de pornire"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Glisează în sus cu trei degete oriunde pe touchpad"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Excelent!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Ai finalizat gestul „înapoi la pagina de pornire”"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Glisează în sus cu trei degete pe touchpad pentru a accesa ecranul de pornire"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Vezi aplicațiile recente"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Glisează în sus și ține apăsat cu trei degete pe touchpad"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Excelent!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Ai finalizat gestul pentru afișarea aplicațiilor recente."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Ca să vezi aplicațiile recente, glisează în sus și ține apăsat cu trei degete pe touchpad"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Vezi toate aplicațiile"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Apasă tasta de acțiuni de pe tastatură"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Felicitări!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Ai finalizat gestul pentru afișarea tuturor aplicațiilor"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Apasă tasta de acțiuni de pe tastatură ca să vezi toate aplicațiile"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Tutorial animat, dă clic pentru a întrerupe și a relua redarea."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Iluminarea din spate a tastaturii"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivelul %1$d din %2$d"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 19ccb08..c534c73 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущее уведомление для записи видео с экрана"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Начать запись экрана?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Записывать одно приложение"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Записывать весь экран"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Записывать весь экран: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"На видео попадет все, что будет происходить на экране. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"На видео попадет все, что происходит в выбранном приложении. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Запись экрана"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не удалось обновить набор настроек."</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набор настроек"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Выбрано"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Инструменты"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Автоматические субтитры"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Заметка"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Показывать значки уведомлений с низким приоритетом"</string>
     <string name="other" msgid="429768510980739978">"Другое"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"удалить панель"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"добавить панель в конец"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Переместить панель"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Добавить панель"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Переместить на позицию <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Добавить на позицию <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Недопустимое расположение."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"выбрать пользователя"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Нет подключения к Интернету."</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Открыть настройки <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Изменить порядок быстрых настроек."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню кнопки питания"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Страница <xliff:g id="ID_1">%1$d</xliff:g> из <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Заблокированный экран"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(нет подключения)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не удается переключиться. Нажмите, чтобы повторить попытку."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Подключить устройство"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Чтобы начать трансляцию сеанса, откройте приложение"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Неизвестное приложение"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Остановить трансляцию"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Доступные устройства для вывода звука."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"На главный экран"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Просмотр недавних приложений"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Попробуйте ещё раз"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Проведите тремя пальцами влево или вправо по сенсорной панели."</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Отлично!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Вы выполнили жест для перехода назад."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Чтобы перейти назад с помощью сенсорной панели, проведите влево или вправо тремя пальцами."</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"На главный экран"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Проведите тремя пальцами вверх по сенсорной панели."</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Отлично!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Вы выполнили жест для перехода на главный экран."</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Чтобы перейти на главный экран, проведите тремя пальцами вверх по сенсорной панели."</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Просмотр недавних приложений"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Проведите вверх по сенсорной панели тремя пальцами и удерживайте."</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Отлично!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Вы выполнили жест для просмотра недавних приложений."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Чтобы увидеть недавние приложения, проведите по сенсорной панели тремя пальцами вверх и удерживайте."</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Все приложения"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Нажмите клавишу действия на клавиатуре."</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Блестяще!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Вы выполнили жест для просмотра всех приложений."</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Чтобы увидеть все свои приложения, нажмите клавишу действия на клавиатуре."</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Анимация в руководстве. Нажмите, чтобы приостановить или продолжить воспроизведение."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Подсветка клавиатуры"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Уровень %1$d из %2$d"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 516b2ae..78331a0 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"තිර පටිගත කිරීමේ සැසියක් සඳහා කෙරෙන දැනුම් දීම"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ඔබේ තිරය පටිගත කරන්න ද?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"එක් යෙදුමක් පටිගත කරන්න"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"සම්පූර්ණ තිරය පටිගත කරන්න"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"සම්පූර්ණ තිරය පටිගත කරන්න: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ඔබ ඔබේ සම්පූර්ණ තිරය පටිගත කරන විට, ඔබේ තිරයේ පෙන්වන ඕනෑම දෙයක් වාර්තා වේ. ඒ නිසා මුරපද, ගෙවීම් විස්තර, පණිවුඩ, ඡායාරූප, සහ ශ්‍රව්‍ය සහ දෘශ්‍ය වැනි දේවල් පිළිබඳ ප්‍රවේශම් වන්න."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ඔබ යෙදුමක් පටිගත කරන විට, එම යෙදුමේ පෙන්වන හෝ වාදනය කරන ඕනෑම දෙයක් වාර්තා වේ. ඒ නිසා මුරපද, ගෙවීම් විස්තර, පණිවුඩ, ඡායාරූප, සහ ශ්‍රව්‍ය සහ දෘශ්‍ය වැනි දේවල් පිළිබඳ ප්‍රවේශම් වන්න."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"තිරය පටිගත කරන්න"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"පෙර සැකසීම යාවත්කාලීන කළ නොහැකි විය"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"පෙරසැකසුම"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"තෝරන ලදි"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"මෙවලම්"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"සජීවී සිරස්තල"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"සටහන"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"අඩු ප්‍රමුඛතා දැනුම්දීම් අයිකන පෙන්වන්න"</string>
     <string name="other" msgid="429768510980739978">"වෙනත්"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ටයිල් ඉවත් කරන්න"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"අගට ටයිල් එක් කරන්න"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ටයිල් ගෙන යන්න"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"ටයිල් එක් කරන්න"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> වෙත ගෙන යන්න"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ස්ථානයට එක් කරන්න"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ස්ථානය අවලංගුයි."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"පරිශීලක තෝරන්න"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"අන්තර්ජාලය නැත"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> සැකසීම් විවෘත කරන්න."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"සැකසීම්වල අනුපිළිවෙළ සංංස්කරණය කරන්න."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"බල මෙනුව"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> න් <xliff:g id="ID_1">%1$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"අගුලු තිරය"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(විසන්ධි විය)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"මාරු කිරීමට නොහැකිය. නැවත උත්සාහ කිරීමට තට්ටු කරන්න."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"උපාංගයක් සම්බන්ධ කරන්න"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"මෙම සැසිය විකාශය කිරීමට, කරුණාකර යෙදුම විවෘත කරන්න."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"නොදන්නා යෙදුම"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"විකාශය නවතන්න"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ශ්‍රව්‍ය ප්‍රතිදානය සඳහා තිබෙන උපාංග."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"මුල් පිටුවට යන්න"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"මෑත යෙදුම් බලන්න"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"නිමයි"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"නැවත උත්සාහ කරන්න!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ආපස්සට යන්න"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"ඔබේ ස්පර්ශ පුවරුව මත ඇඟිලි තුනක් භාවිතයෙන් වමට හෝ දකුණට ස්වයිප් කරන්න"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"කදිමයි!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"ඔබ ආපසු යාමේ ඉංගිතය සම්පූර්ණ කරන ලදි."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"ඔබේ ස්පර්ශ පෑඩය භාවිතයෙන් ආපසු යාමට, ඇඟිලි තුනක් භාවිතයෙන් වමට හෝ දකුණට ස්වයිප් කරන්න"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"මුල් පිටුවට යන්න"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"ඔබේ ස්පර්ශ පුවරුවේ ඇඟිලි තුනකින් ඉහළට ස්වයිප් කරන්න"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"අනර්ඝ වැඩක්!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"ඔබ මුල් පිටුවට යාමේ ඉංගිතය සම්පූර්ණ කරන ලදි"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"ඔබේ මුල් තිරයට යාමට ඔබේ ස්පර්ශක පෑඩයේ ඇඟිලි තුනකින් ඉහළට ස්වයිප් කරන්න"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"මෑත යෙදුම් බලන්න"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"ඉහළට ස්වයිප් කර ඔබේ ස්පර්ශ පුවරුව මත ඇඟිලි තුනක් භාවිත කර රඳවාගෙන සිටින්න"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"අනර්ඝ වැඩක්!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ඔබ මෑත යෙදුම් ඉංගිත බැලීම සම්පූර්ණ කර ඇත."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"මෑත කාලීන යෙදුම් බැලීමට, ඔබේ ස්පර්ශක පෑඩයේ ඇඟිලි තුනක් භාවිතයෙන් ඉහළට ස්වයිප් කරගෙන සිටින්න"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"සියලු යෙදුම් බලන්න"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"ඔබේ යතුරු පුවරුවේ ක්‍රියාකාරී යතුර ඔබන්න"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"හොඳින් කළා!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"ඔබ සියලු යෙදුම් ඉංගිත බැලීම සම්පූර්ණ කර ඇත"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"ඔබේ සියලු යෙදුම් බැලීමට ඔබගේ යතුරු පුවරුවේ ක්‍රියා යතුර ඔබන්න"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"නිබන්ධන සජීවීකරණය, ක්‍රීඩාව විරාම කිරීමට සහ නැවත ආරම්භ කිරීමට ක්ලික් කරන්න."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"යතුරු පුවරු පසු ආලෝකය"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dන් %1$d වැනි මට්ටම"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 1b2dc5a..cf8972e 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Zobrazuje sa upozornenie týkajúce sa relácie záznamu obrazovky"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Chcete nahrávať obrazovku?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Nahrávať jednu aplikáciu"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Nahrávať celú obrazovku"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Nahrať celú obrazovku: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Pri nahrávaní celej obrazovky sa zaznamená všetko, čo sa na nej zobrazuje. Preto venujte pozornosť položkám, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Pri nahrávaní aplikácie sa zaznamená všetko, čo sa v nej zobrazuje alebo prehráva. Preto venujte pozornosť položkám, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Nahrávať obrazovku"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Predvoľbu sa nepodarilo aktualizovať"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predvoľba"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Vybrané"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nástroje"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Živý prepis"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Poznámka"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Zobraziť ikony upozornení s nízkou prioritou"</string>
     <string name="other" msgid="429768510980739978">"Ďalšie"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"odstrániť kartu"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"pridať kartu na koniec"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Presunúť kartu"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Pridať kartu"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Presunúť na <xliff:g id="POSITION">%1$d</xliff:g>. pozíciu"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Pridať na <xliff:g id="POSITION">%1$d</xliff:g>. pozíciu"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozícia je neplatná."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"vybrať používateľa"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Žiadny internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Otvoriť nastavenia <xliff:g id="ID_1">%s</xliff:g>"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Upraviť poradie nastavení"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Ponuka vypínača"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Strana <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Uzamknutá obrazovka"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(odpojené)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nedá sa prepnúť. Zopakujte klepnutím."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Pripojiť zariadenie"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ak chcete túto reláciu prenášať, otvorte aplikáciu."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznáma aplikácia"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zastaviť prenos"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Dostupné zariadenia pre zvukový výstup."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Prejsť na plochu"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Zobrazenie nedávnych aplikácií"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Hotovo"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Skúste to znova."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Prejdenie späť"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Potiahnite troma prstami na touchpade doľava alebo doprava"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Výborne!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Použili ste gesto na prechod späť."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Ak chcete prejsť späť pomocou touchpadu, potiahnite troma prstami doľava alebo doprava"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Prechod na plochu"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Potiahnite troma prstami na touchpade nahor"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Skvelé!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Použili ste gesto na prechod na plochu."</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Ak chcete prejsť na plochu, potiahnite troma prstami na touchpade"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Zobrazenie nedávnych aplikácií"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Potiahnite troma prstami na touchpade nahor a pridržte"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Skvelé!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Použili ste gesto na zobrazenie nedávnych aplikácií."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Ak si chcete zobraziť nedávne aplikácie, potiahnite troma prstami na touchpade nahor a pridržte ich"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Zobrazenie všetkých aplikácií"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Stlačte na klávesnici akčný kláves"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Dobre!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Použili ste gesto na zobrazenie všetkých aplikácií."</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Ak si chcete zobraziť všetky aplikácie, stlačte na klávesnici akčný kláves"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Výuková animácia, kliknutím pozastavíte alebo obnovíte prehrávanie."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvietenie klávesnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. úroveň z %2$d"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 76ce78c..d0063fd 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Nenehno obveščanje o seji snemanja zaslona"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Želite posneti zaslon?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snemanje ene aplikacije"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snemanje celotnega zaslona"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Snemanje celotnega zaslona: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Pri snemanju celotnega zaslona se posname vse, kar je prikazano na zaslonu. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Pri snemanju aplikacije se posname vse, kar je prikazano ali predvajano v tej aplikaciji. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snemanje zaslona"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Prednastavljenih vrednosti ni bilo mogoče posodobiti"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Prednastavljeno"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Izbrano"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Orodja"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Samodejni podnapisi"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Opomba"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Pokaži ikone obvestil z nizko stopnjo prednosti"</string>
     <string name="other" msgid="429768510980739978">"Drugo"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"odstranitev ploščice"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"dodajanje ploščice na konec"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Premik ploščice"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Dodajanje ploščice"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Premik na položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodajanje na položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Položaj je neveljaven."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"izbiro uporabnika"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Brez internetne povezave"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Odpri nastavitve za <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Uredi vrstni red nastavitev."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meni za vklop/izklop"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. stran od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaklenjen zaslon"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(povezava je prekinjena)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Preklop ni mogoč. Če želite poskusiti znova, se dotaknite."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Povežite napravo"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Če želite predvajati to sejo, odprite aplikacijo."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznana aplikacija"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ustavi predvajanje"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Razpoložljive naprave za zvočni izhod"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Pomik na začetni zaslon"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Ogled nedavnih aplikacij"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Končano"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Poskusite znova"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazaj"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Na sledilni ploščici s tremi prsti povlecite levo ali desno"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Odlično!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Izvedli ste potezo za pomik nazaj."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Za pomik nazaj na sledilni ploščici povlecite v levo ali desno s tremi prsti"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Pomik na začetni zaslon"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Na sledilni ploščici s tremi prsti povlecite navzgor"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Odlično!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Izvedli ste potezo za pomik na začetni zaslon"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Za vrnitev na začetni zaslon povlecite s tremi prsti navzgor po sledilni ploščici"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Ogled nedavnih aplikacij"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Na sledilni ploščici s tremi prsti povlecite navzgor in pridržite"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Odlično!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Izvedli ste potezo za ogled nedavnih aplikacij."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Za ogled nedavnih aplikacij povlecite s tremi prsti navzgor po sledilni ploščici in pridržite"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Ogled vseh aplikacij"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Pritisnite tipko za dejanja na tipkovnici"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Odlično!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Izvedli ste potezo za ogled vseh aplikacij"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Za ogled vseh aplikacij pritisnite tipko za dejanja na tipkovnici"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animacija v vadnici, kliknite za začasno zaustavitev in nadaljevanje predvajanja."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Osvetlitev tipkovnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Stopnja %1$d od %2$d"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index dd13cff..803a5e5 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Njoftim i vazhdueshëm për një seancë regjistrimi të ekranit"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Të regjistrohet ekrani?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Regjistro një aplikacion"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Regjistro të gjithë ekranin"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Regjistro gjithë ekranin: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kur regjistron të gjithë ekranin, regjistrohet çdo gjë e shfaqur në ekranin tënd. Prandaj, ki kujdes me gjërat si fjalëkalimet, detajet e pagesave, mesazhet, fotografitë, si dhe audion dhe videon."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kur regjistron një aplikacion, regjistrohet çdo gjë që shfaqet ose luhet në atë aplikacion. Prandaj, ki kujdes me gjërat si fjalëkalimet, detajet e pagesave, mesazhet, fotografitë, si dhe audion dhe videon."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Regjistro ekranin"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Paravendosja nuk mund të përditësohej"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Paravendosja"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Zgjedhur"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Veglat"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Titrat në çast"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Shënim"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Shfaq ikonat e njoftimeve me përparësi të ulët"</string>
     <string name="other" msgid="429768510980739978">"Të tjera"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"hiq pllakëzën"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"shto pllakëzën në fund"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Zhvendos pllakëzën"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Shto pllakëzën"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Zhvendos te <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Shto te pozicioni <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozicion i pavlefshëm."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"zgjidh përdoruesin"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Nuk ka internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Hap cilësimet e <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Modifiko rendin e cilësimeve."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menyja e energjisë"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Faqja <xliff:g id="ID_1">%1$d</xliff:g> nga <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekrani i kyçjes"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(shkëputur)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Nuk mund të ndërrohet. Trokit për të provuar përsëri."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Lidh një pajisje"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Hap aplikacionin për të transmetuar këtë seancë."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikacion i panjohur"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ndalo transmetimin"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Pajisjet që ofrohen për daljen e audios."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Shko tek ekrani bazë"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Shiko aplikacionet e fundit"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"U krye"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Provo përsëri!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kthehu prapa"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Rrëshqit shpejt majtas ose djathtas duke përdorur tre gishta në bllokun me prekje"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bukur!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"E ke përfunduar gjestin e kthimit prapa."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Për t\'u kthyer prapa duke përdorur bllokun me prekje, rrëshqit shpejt majtas ose djathtas duke përdorur tre gishta"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Shko tek ekrani bazë"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Rrëshqit shpejt lart me tre gishta në bllokun me prekje"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Punë e shkëlqyer!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"E ke përfunduar gjestin e kalimit tek ekrani bazë"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Rrëshqit shpejt lart me tre gishta në bllokun me prekje për të shkuar tek ekrani bazë"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Shiko aplikacionet e fundit"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Rrëshqit shpejt lart dhe mbaj shtypur me tre gishta në bllokun me prekje"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Punë e shkëlqyer!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Përfundove gjestin për shikimin e aplikacioneve të fundit."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Për të shikuar aplikacionet e fundit, rrëshqit shpejt lart dhe mbaj shtypur me tre gishta në bllokun me prekje"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Shiko të gjitha aplikacionet"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Shtyp tastin e veprimit në tastierë"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Shumë mirë!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Përfundove gjestin për shikimin e të gjitha aplikacioneve"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Shtyp tastin e veprimit në tastierë për të shikuar të gjitha aplikacionet e tua"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animacioni udhëzues. Kliko për të vendosur në pauzë dhe për të vazhduar luajtjen."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Drita e sfondit e tastierës"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveli: %1$d nga %2$d"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 5693956..1787072 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Обавештење о сесији снимања екрана је активно"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Желите да снимите екран?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Сними једну апликацију"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Сними цео екран"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Снимите цео екран: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Када снимате цео екран, снима се све што је на њему. Зато пазите на лозинке, информације о плаћању, поруке, слике, аудио и видео садржај."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Када снимате апликацију, снима се сав садржај који се приказује или пушта у њој. Зато пазите на лозинке, информације о плаћању, поруке, слике, аудио и видео садржај."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Сними екран"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ажурирање задатих подешавања није успело"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Унапред одређена подешавања"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Изабрано"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Алатке"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Титл уживо"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Белешка"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Прикажи иконе обавештења ниског приоритета"</string>
     <string name="other" msgid="429768510980739978">"Друго"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"уклонили плочицу"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"додали плочицу на крај"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Преместите плочицу"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Додајте плочицу"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Преместите на <xliff:g id="POSITION">%1$d</xliff:g>. позицију"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додајте на <xliff:g id="POSITION">%1$d</xliff:g>. позицију"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Позиција је неважећа."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"одабрали корисника"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Нема интернета"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Отвори подешавања за <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Измени редослед подешавања."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Мени дугмета за укључивање"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. страна од <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Закључан екран"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(веза је прекинута)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Пребацивање није успело. Пробајте поново."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Повежите уређај"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Да бисте пребацивали ову сесију, отворите апликацију."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Заустави пребацивање"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Доступни уређаји за аудио излаз."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Иди на почетни екран"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Прикажи недавно коришћене апликације"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Пробајте поново."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Превуците улево или удесно са три прста на тачпеду"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Супер!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Довршили сте покрет за повратак."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Да бисте се вратили помоћу тачпеда, превуците улево или удесно са три прста"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Иди на почетни екран"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Превуците нагоре са три прста на тачпеду"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Одлично!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Довршили сте покрет за повратак на почетну страницу."</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Да бисте отишли на почетни екран, превуците нагоре са три прста на тачпеду"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Прикажи недавно коришћене апликације"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Превуците нагоре и задржите са три прста на тачпеду"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Одлично!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Довршили сте покрет за приказивање недавно коришћених апликација."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Да бисте прегледали недавне апликације, превуците нагоре и задржите са три прста на тачпеду"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Прикажи све апликације"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Притисните тастер радњи на тастатури"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Одлично!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Довршили сте покрет за приказивање свих апликација."</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Притисните тастер радњи на тастатури да бисте прегледали све апликације"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Анимација водича, кликните да бисте паузирали и наставили репродукцију."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Позадинско осветљење тастатуре"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. ниво од %2$d"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 7d1f755..6d9f721 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Avisering om att skärminspelning pågår"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vill du spela in det som visas på skärmen?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Spela in en app"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Spela in hela skärmen"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Spela in hela skärmen: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"När du spelar in hela skärmen spelas allt som visas på skärmen in. Var försiktig med sådant som lösenord, betalningsuppgifter, meddelanden, foton, ljud och video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"När du spelar in en app spelas allt som visas eller spelas upp i appen in. Var försiktig med sådant som lösenord, betalningsuppgifter, meddelanden, foton, ljud och video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Spela in skärmen"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Det gick inte att uppdatera förinställningen"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Förinställning"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Markerad"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verktyg"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Anteckning"</string>
@@ -960,9 +976,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Visa ikoner för aviseringar med låg prioritet"</string>
     <string name="other" msgid="429768510980739978">"Annat"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ta bort ruta"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"lägg till ruta i slutet"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"lägg till en ruta på den sista platsen"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Flytta ruta"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Lägg till ruta"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Lägg till en ruta på önskad plats"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Flytta till <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Lägg till på position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Positionen är ogiltig."</string>
@@ -978,7 +994,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"välj användare"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Inget internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Öppna <xliff:g id="ID_1">%s</xliff:g>-inställningarna."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Ändra ordning på inställningarna."</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"Ändra ordningen på snabbinställningarna."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Startmeny"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Sida <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Låsskärm"</string>
@@ -1209,7 +1225,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(frånkopplad)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Misslyckat byte. Tryck och försök igen."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Anslut en enhet"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Öppna appen om du vill casta den här sessionen."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Okänd app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Sluta casta"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Enheter som är tillgängliga för ljudutdata."</string>
@@ -1468,32 +1483,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Återvänd till startsidan"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Se de senaste apparna"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Klar"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Försök igen!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Tillbaka"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Svep åt vänster eller höger med tre fingrar på styrplattan"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Bra!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Du är klar med rörelsen för att gå tillbaka."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Svep åt vänster eller höger med tre fingrar på styrplattan för att gå tillbaka"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Återvänd till startskärmen"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Svep uppåt med tre fingrar på styrplattan"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Bra jobbat!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Du är klar med rörelsen för att öppna startskärmen"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Svep uppåt med tre fingrar på styrplattan för att öppna startskärmen"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Se de senaste apparna"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Svep uppåt med tre fingrar på styrplattan och håll kvar"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Bra jobbat!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Du är klar med rörelsen för att se de senaste apparna."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Svep uppåt på styrplattan med tre fingrar och håll kvar för att se nyligen använda appar"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Visa alla appar"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Tryck på åtgärdstangenten på tangentbordet"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Bra gjort!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Du är klar med rörelsen för att se alla apparna."</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Tryck på åtgärdstangenten på tangentbordet för att se alla dina appar"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Animation för guiden: Klicka för att pausa och återuppta uppspelningen."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Bakgrundsbelysning för tangentbord"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivå %1$d av %2$d"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index a17d645..6fb8f08 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Arifa inayoendelea ya kipindi cha kurekodi skrini"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ungependa kurekodi skrini yako?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Rekodi programu moja"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Rekodi skrini nzima"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Rekodi skrini nzima: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Unaporekodi skrini yako nzima, chochote kinachoonyeshwa kwenye skrini yako kitarekodiwa. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha, sauti na video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Unaporekodi programu, chochote kinachoonyeshwa au kuchezwa kwenye programu hiyo kitarekodiwa. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha, sauti na video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Rekodi skrini"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Imeshindwa kusasisha mipangilio iliyowekwa mapema"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Mipangilio iliyowekwa mapema"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Umechagua"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Zana"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Manukuu Papo Hapo"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Dokezo"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Onyesha aikoni za arifa zisizo muhimu"</string>
     <string name="other" msgid="429768510980739978">"Nyingine"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ondoa kigae"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ongeza kigae mwishoni"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Hamisha kigae"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Ongeza kigae"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Hamishia kwenye <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ongeza kwenye nafasi ya <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nafasi si sahihi."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"chagua mtumiaji"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Hakuna intaneti"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Fungua mipangilio ya <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Badilisha orodha ya mipangilio."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menyu ya kuzima/kuwasha"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Ukurasa wa <xliff:g id="ID_1">%1$d</xliff:g> kati ya <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Skrini iliyofungwa"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(imetenganishwa)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Imeshindwa kubadilisha. Gusa ili ujaribu tena."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Unganisha kifaa"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ili utume kipindi hiki, tafadhali fungua programu."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Programu isiyojulikana"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Acha kutuma"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Vifaa vya kutoa sauti vilivyopo"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Nenda kwenye ukurasa wa mwanzo"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Angalia programu za hivi majuzi"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Nimemaliza"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Jaribu tena!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Rudi nyuma"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Telezesha vidole vitatu kushoto au kulia kwenye padi yako ya kugusa"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Safi!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Umekamilisha mafunzo ya miguso ya kurudi nyuma."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Ili uendelee kutumia padi yako ya kugusa, telezesha kushoto au kulia ukitumia vidole vitatu"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Nenda kwenye skrini ya kwanza"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Telezesha vidole vitatu juu kwenye padi yako ya kugusa"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Kazi nzuri!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Umeweka ishara ya kwenda kwenye skrini ya kwanza"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Telezesha vidole vitatu juu kwenye padi yako ya kugusa ili uende kwenye skrini yako ya kwanza"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Angalia programu za hivi majuzi"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Telezesha vidole vitatu juu kisha ushikilie kwenye padi yako ya kugusa"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Kazi nzuri!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Umekamilisha mafunzo ya mguso wa kuangalia programu za hivi majuzi."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Telezesha vidole vitatu juu na ushikilie kwenye padi yako ya kugusa ili uangalie programu za hivi majuzi"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Angalia programu zote"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Bonyeza kitufe cha vitendo kwenye kibodi yako"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Vizuri sana!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Umekamilisha mafunzo ya mguso wa kuangalia programu zote"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Bonyeza kitufe cha vitendo kwenye kibodi yako ili uangalie programu zako zote"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Uhuishaji wa mafunzo, bofya ili usitishe na uendelee kucheza."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Mwanga chini ya kibodi"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Kiwango cha %1$d kati ya %2$d"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 3270e5e..ead1f83 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"திரை ரெக்கார்டிங் அமர்விற்கான தொடர் அறிவிப்பு"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"உங்கள் திரையை ரெக்கார்டு செய்யவா?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ஓர் ஆப்ஸை ரெக்கார்டு செய்தல்"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"முழுத் திரையை ரெக்கார்டு செய்தல்"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"முழுத் திரையை ரெக்கார்டு செய்தல்: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"முழுத் திரையை நீங்கள் ரெக்கார்டு செய்யும்போது அதில் காட்டப்படும் அனைத்தும் ரெக்கார்டு செய்யப்படும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள், படங்கள், ஆடியோ, வீடியோ போன்றவை குறித்துக் கவனத்துடன் இருங்கள்."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ஓர் ஆப்ஸை ரெக்கார்டு செய்யும்போது அதில் காட்டப்படும் அல்லது பிளே செய்யப்படும் அனைத்தும் ரெக்கார்டு செய்யப்படும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள், படங்கள், ஆடியோ, வீடியோ போன்றவை குறித்துக் கவனத்துடன் இருங்கள்."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"திரையை ரெக்கார்டு செய்"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"முன்னமைவைப் புதுப்பிக்க முடியவில்லை"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"முன்னமைவு"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"தேர்ந்தெடுக்கப்பட்டது"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"கருவிகள்"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"உடனடி வசனம்"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"குறிப்பு"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"குறைந்த முன்னுரிமை உள்ள அறிவிப்பு ஐகான்களைக் காட்டு"</string>
     <string name="other" msgid="429768510980739978">"மற்றவை"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"கட்டத்தை அகற்றும்"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"கடைசியில் கட்டத்தைச் சேர்க்கும்"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"கட்டத்தை நகர்த்து"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"கட்டத்தைச் சேர்"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g>க்கு நகர்த்தும்"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g>ல் சேர்க்கும்"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"நிலை தவறானது."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"பயனரைத் தேர்வுசெய்யவும்"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"இணைய இணைப்பு இல்லை"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> அமைப்புகளைத் திற."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"அமைப்புகளின் வரிசை முறையைத் திருத்து."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"பவர் மெனு"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"பக்கம் <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"லாக் ஸ்கிரீன்"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(துண்டிக்கப்பட்டது)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"இணைக்க முடியவில்லை. மீண்டும் முயல தட்டவும்."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"சாதனத்தை இணை"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"இந்த அமர்வை அலைபரப்ப ஆப்ஸைத் திறங்கள்."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"அறியப்படாத ஆப்ஸ்"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"அலைபரப்புவதை நிறுத்து"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ஆடியோ அவுட்புட்டுக்குக் கிடைக்கும் சாதனங்கள்."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"முகப்பிற்குச் செல்"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"சமீபத்திய ஆப்ஸைக் காட்டுதல்"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"முடிந்தது"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"மீண்டும் முயலவும்!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"பின்செல்"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"உங்கள் டச்பேடில் மூன்று விரல்களால் இடது அல்லது வலதுபுறம் ஸ்வைப் செய்யவும்"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"அருமை!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"பின்செல்வதற்கான சைகையை நிறைவுசெய்துவிட்டீர்கள்."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"உங்கள் டச்பேடைப் பயன்படுத்திப் பின்செல்ல, மூன்று விரல்களால் இடது அல்லது வலதுபுறம் ஸ்வைப் செய்யவும்"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"முகப்பிற்குச் செல்"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"டச்பேடில் மூன்று விரல்களால் மேல்நோக்கி ஸ்வைப் செய்யவும்"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"அருமை!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"முகப்புக்குச் செல்வதற்கான சைகைப் பயிற்சியை நிறைவுசெய்துவிட்டீர்கள்"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"உங்கள் முகப்புத் திரைக்குச் செல்ல டச்பேடில் மூன்று விரல்களால் மேல்நோக்கி ஸ்வைப் செய்யவும்"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"சமீபத்திய ஆப்ஸைக் காட்டுதல்"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"உங்கள் டச்பேடில் மூன்று விரல்களால் மேல்நோக்கி ஸ்வைப் செய்து பிடிக்கவும்"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"அருமை!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"சமீபத்தில் பயன்படுத்திய ஆப்ஸுக்கான சைகை பயிற்சியை நிறைவுசெய்துவிட்டீர்கள்."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"சமீபத்திய ஆப்ஸைப் பார்க்க, உங்கள் டச்பேடில் மூன்று விரல்களால் மேல்நோக்கி ஸ்வைப் செய்து பிடிக்கவும்"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"அனைத்து ஆப்ஸையும் காட்டு"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"உங்கள் கீபோர்டில் ஆக்‌ஷன் பட்டனை அழுத்தவும்"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"அருமை!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"அனைத்து ஆப்ஸையும் பார்ப்பதற்கான சைகை பயிற்சியை நிறைவுசெய்துவிட்டீர்கள்"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"உங்களின் அனைத்து ஆப்ஸையும் பார்க்க, உங்கள் கீபோர்டில் உள்ள ஆக்ஷன் பட்டனை அழுத்தவும்"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"பயிற்சி அனிமேஷன், இடைநிறுத்தவும் மீண்டும் இயக்கவும் கிளிக் செய்யலாம்."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"கீபோர்டு பேக்லைட்"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"நிலை, %2$d இல் %1$d"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index ea02e4f..73a4250 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"స్క్రీన్ రికార్డ్ సెషన్ కోసం ఆన్‌గోయింగ్ నోటిఫికేషన్"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"మీ స్క్రీన్‌ను రికార్డ్ చేయాలా?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ఒక యాప్‌ను రికార్డ్ చేయండి"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ఫుల్ స్క్రీన్‌ను రికార్డ్ చేయండి"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"ఫుల్-స్క్రీన్‌ను రికార్డ్ చేయండి: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"మీ ఫుల్ స్క్రీన్‌ను మీరు రికార్డ్ చేసేటప్పుడు, మీ స్క్రీన్‌పై కనిపించేవన్నీ రికార్డ్ అవుతాయి. కాబట్టి పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"మీరు యాప్‌ను రికార్డ్ చేసేటప్పుడు, సంబంధిత యాప్‌లో కనిపించేవన్నీ లేదా ప్లే అయ్యేవన్నీ రికార్డ్ అవుతాయి. కాబట్టి పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"స్క్రీన్‌ను రికార్డ్ చేయండి"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ప్రీసెట్‌ను అప్‌డేట్ చేయడం సాధ్యపడలేదు"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ప్రీసెట్"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ఎంచుకోబడింది"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"టూల్స్"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"లైవ్ క్యాప్షన్"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"గమనిక"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"తక్కువ ప్రాధాన్యత నోటిఫికేషన్ చిహ్నాలను చూపించు"</string>
     <string name="other" msgid="429768510980739978">"ఇతరం"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"టైల్‌ను తీసివేయండి"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ముగించడానికి టైల్‌ను జోడించండి"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"టైల్‌ను తరలించండి"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"టైల్‌ను జోడించండి"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g>కు తరలించండి"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> స్థానానికి జోడించండి"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ప్రస్తుత పొజిషన్ చెల్లదు."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"యూజర్‌ను ఎంపిక చేయండి"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ఇంటర్నెట్ లేదు"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> సెట్టింగ్‌లను తెరవండి."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"సెట్టింగ్‌ల క్రమాన్ని ఎడిట్ చేయండి."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"పవర్ మెనూ"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>లో <xliff:g id="ID_1">%1$d</xliff:g>వ పేజీ"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"లాక్ స్క్రీన్"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(డిస్కనెక్ట్ అయ్యింది)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"స్విచ్ చేయడం సాధ్యం కాదు. మళ్ళీ ట్రై చేయడానికి ట్యాప్ చేయండి."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"పరికరాన్ని కనెక్ట్ చేయండి"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ఈ సెషన్‌ను ప్రసారం చేయడానికి, దయచేసి యాప్‌ను తెరవండి."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"తెలియని యాప్"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ప్రసారాన్ని ఆపివేయండి"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ఆడియో అవుట్‌పుట్ కోసం అందుబాటులో ఉన్న పరికరాలు."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"మొదటి ట్యాబ్‌కు వెళ్లండి"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"ఇటీవలి యాప్‌లను చూడండి"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"పూర్తయింది"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"మళ్లీ ట్రై చేయండి!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"వెనుకకు"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"మీ టచ్‌ప్యాడ్‌లో మూడు వేళ్లను ఉపయోగించి ఎడమ వైపునకు లేదా కుడి వైపునకు స్వైప్ చేయండి"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"సూపర్!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"తిరిగి వెనుకకు వెళ్ళడానికి ఉపయోగించే సంజ్ఞకు సంబంధించిన ట్యుటోరియల్‌ను మీరు పూర్తి చేశారు."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"మీ టచ్‌ప్యాడ్‌ను ఉపయోగించి తిరిగి వెనక్కి వెళ్లడానికి, మూడు వేళ్లను ఉపయోగించి ఎడమ వైపునకు లేదా కుడి వైపునకు స్వైప్ చేయండి"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"మొదటి ట్యాబ్‌కు వెళ్లండి"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"మీ టచ్‌ప్యాడ్‌పై మూడు వేళ్లతో పైకి స్వైప్ చేయండి"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"చక్కగా పూర్తి చేశారు!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"మీరు మొదటి స్క్రీన్‌కు వెళ్లే సంజ్ఞను పూర్తి చేశారు"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"మీ మొదటి స్క్రీన్‌కు వెళ్లడానికి మీ టచ్‌ప్యాడ్‌పై మూడు వేళ్లతో పైకి స్వైప్ చేయండి"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"ఇటీవలి యాప్‌లను చూడండి"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"మీ టచ్‌ప్యాడ్‌లో మూడు వేళ్లను ఉపయోగించి పైకి స్వైప్ చేసి, హోల్డ్ చేయండి"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"చక్కగా పూర్తి చేశారు!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"ఇటీవలి యాప్‌లను చూడడానికి ఉపయోగించే సంజ్ఞకు సంబంధించిన ట్యుటోరియల్‌ను మీరు పూర్తి చేశారు."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"ఇటీవలి యాప్‌లను చూడటానికి, మీ టచ్‌ప్యాడ్‌లో మూడు వేళ్లను ఉపయోగించి పైకి స్వైప్ చేసి, హోల్డ్ చేయండి"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"అన్ని యాప్‌లను చూడండి"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"మీ కీబోర్డ్‌లో యాక్షన్ కీని నొక్కండి"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"చక్కగా చేశారు!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"అన్ని యాప్‌లను చూడడానికి ఉపయోగించే సంజ్ఞకు సంబంధించిన ట్యుటోరియల్‌ను మీరు పూర్తి చేశారు"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"మీ యాప్‌లన్నింటినీ చూడటానికి మీ కీబోర్డ్‌లోని యాక్షన్ కీని నొక్కండి"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"ట్యుటోరియల్ యానిమేషన్, పాజ్ చేసి, మళ్లీ ప్లే చేయడానికి క్లిక్ చేయండి."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"కీబోర్డ్ బ్యాక్‌లైట్"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dలో %1$dవ స్థాయి"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index f8c4327..c46a9d7 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"การแจ้งเตือนต่อเนื่องสำหรับเซสชันการบันทึกหน้าจอ"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"บันทึกหน้าจอไหม"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"บันทึกแอปเดียว"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"บันทึกทั้งหน้าจอ"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"บันทึกทั้งหน้าจอ: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ขณะบันทึกทั้งหน้าจอ ระบบจะบันทึกทุกสิ่งที่แสดงอยู่บนหน้าจอ ดังนั้นโปรดระวังสิ่งต่างๆ อย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ รูปภาพ รวมถึงเสียงและวิดีโอ"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ขณะบันทึกแอป ระบบจะบันทึกทุกสิ่งที่แสดงหรือเล่นอยู่ในแอปดังกล่าว ดังนั้นโปรดระวังสิ่งต่างๆ อย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ รูปภาพ รวมถึงเสียงและวิดีโอ"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"บันทึกหน้าจอ"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ไม่สามารถอัปเดตค่าที่กำหนดล่วงหน้า"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ค่าที่กำหนดล่วงหน้า"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"เลือกแล้ว"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"เครื่องมือ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"คำบรรยายสด"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"จดบันทึก"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"แสดงไอคอนการแจ้งเตือนลำดับความสำคัญต่ำ"</string>
     <string name="other" msgid="429768510980739978">"อื่นๆ"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"นำชิ้นส่วนออก"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"เพิ่มชิ้นส่วนต่อท้าย"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ย้ายชิ้นส่วน"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"เพิ่มชิ้นส่วน"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"ย้ายไปที่ <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"เพิ่มไปยังตำแหน่ง <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ตำแหน่งไม่ถูกต้อง"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"เลือกผู้ใช้"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"ไม่มีอินเทอร์เน็ต"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"เปิดการตั้งค่า <xliff:g id="ID_1">%s</xliff:g>"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"แก้ไขลำดับการตั้งค่า"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"เมนูเปิด/ปิด"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"หน้า <xliff:g id="ID_1">%1$d</xliff:g> จาก <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"หน้าจอล็อก"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(ยกเลิกการเชื่อมต่อแล้ว)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"เปลี่ยนไม่ได้ แตะเพื่อลองอีกครั้ง"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"เชื่อมต่ออุปกรณ์"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"โปรดเปิดแอปหากต้องการแคสต์เซสชันนี้"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"แอปที่ไม่รู้จัก"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"หยุดแคสต์"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"อุปกรณ์ที่พร้อมใช้งานสำหรับเอาต์พุตเสียง"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index c47da32..6953458 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Kasalukuyang notification para sa session ng pag-record ng screen"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"I-record ang iyong screen?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Mag-record ng isang app"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"I-record ang buong screen"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"I-record ang buong screen: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kapag nire-record mo ang iyong buong screen, nire-record ang anumang ipinapakita sa screen mo. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kapag nagre-record ka ng app, nire-record ang anumang ipinapakita o pine-play sa app na iyon. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"I-record ang screen"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Hindi ma-update ang preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Napili"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Mga Tool"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Instant Caption"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Tala"</string>
@@ -960,9 +976,9 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Ipakita ang mga icon ng notification na may mababang priority"</string>
     <string name="other" msgid="429768510980739978">"Iba pa"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"alisin ang tile"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"idagdag ang tile sa dulo"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"magdagdag ng tile sa huling posisyon"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Ilipat ang tile"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Magdagdag ng tile"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Magdagdag ng tile sa gustong posisyon"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Ilipat sa <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Idagdag sa posisyong <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Invalid ang posisyon."</string>
@@ -978,7 +994,7 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"pumili ng user"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Walang internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Buksan ang mga setting ng <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"I-edit ang pagkakasunud-sunod ng mga setting."</string>
+    <string name="accessibility_quick_settings_edit" msgid="6544873823850165">"I-edit ang pagkakasunod-sunod ng Mga Mabilisang Setting."</string>
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> ng <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string>
@@ -1209,7 +1225,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(nadiskonekta)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Hindi makalipat. I-tap para subukan ulit."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Magkonekta ng device"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para ma-cast ang session na ito, buksan ang app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Hindi kilalang app"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ihinto ang pag-cast"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Mga available na device para sa audio output."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 2a3c4426..441cec1 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekran kaydı oturumu için devam eden bildirim"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ekranınız kaydedilsin mi?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Bir uygulamayı kaydet"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Tüm ekranı kaydet"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Tüm ekranı kaydet: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Ekranın tamamını kaydederken ekranınızda gösterilen her şey kaydedilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Bir uygulamayı kaydettiğinizde o uygulamada gösterilen veya oynatılan her şey kaydedilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekranı kaydet"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Hazır ayar güncellenemedi"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Hazır Ayar"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seçili"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Araçlar"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Canlı Altyazı"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Not"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Düşük öncelikli bildirim simgelerini göster"</string>
     <string name="other" msgid="429768510980739978">"Diğer"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"Kutuyu kaldırmak için"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"Sona kutu eklemek için"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Kutuyu taşı"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Kutu ekle"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> konumuna taşı"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> konumuna ekle"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Konum geçersiz."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"kullanıcı seç"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"İnternet yok"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ayarlarını aç."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Ayarların sırasını düzenle."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Güç menüsü"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Sayfa <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Kilit ekranı"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(bağlantı kesildi)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Geçiş yapılamıyor. Tekrar denemek için dokunun."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Cihaz bağla"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu oturumu yayınlamak için lütfen uygulamayı açın."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Bilinmeyen uygulama"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Yayını durdur"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Ses çıkışı için kullanılabilir cihazlar."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Ana sayfaya git"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Son uygulamaları görüntüle"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Bitti"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Tekrar deneyin."</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Geri dön"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Dokunmatik alanda üç parmağınızla sola veya sağa kaydırın"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Güzel!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Geri dön hareketini tamamladınız."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Dokunmatik alanı kullanarak geri dönmek için üç parmağınızla sola veya sağa kaydırın"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Ana sayfaya gidin"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Dokunmatik alanda üç parmağınızla yukarı kaydırın"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Tebrikler!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Ana ekrana git hareketini tamamladınız"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Ana ekranınıza gitmek için dokunmatik alanda üç parmağınızla yukarı kaydırın"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Son uygulamaları görüntüle"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Dokunmatik alanda üç parmağınızla yukarı doğru kaydırıp basılı tutun"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Tebrikler!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Son uygulamaları görüntüleme hareketini tamamladınız."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Son kullanılan uygulamaları görüntülemek için dokunmatik alanda üç parmağınızla yukarı kaydırıp basılı tutun"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Tüm uygulamaları göster"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Klavyenizde eylem tuşuna basın"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Tebrikler!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Tüm uygulamaları görüntüleme hareketini tamamladınız"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Tüm uygulamalarınızı görüntülemek için klavyenizdeki eylem tuşuna basın"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Eğitim animasyonu, oynatmayı duraklatmak ve sürdürmek için tıklayın."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klavye aydınlatması"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Seviye %1$d / %2$d"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 68129a8..af70c6f 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Сповіщення про сеанс запису екрана"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Записати відео з екрана?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Записувати один додаток"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Записувати весь екран"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Записувати весь вміст екрана: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Коли ви записуєте вміст усього екрана, на відео потрапляє все, що на ньому відображається. Тому будьте уважні з паролями, повідомленнями, фотографіями, аудіо, відео, платіжною інформацією тощо."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Коли ви записуєте додаток, на відео потрапляє все, що відображається або відтворюється в ньому. Тому будьте уважні з паролями, повідомленнями, фотографіями, аудіо, відео, платіжною інформацією тощо."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Записувати вміст екрана"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не вдалось оновити набір налаштувань"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набір налаштувань"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Вибрано"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Інструменти"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Живі субтитри"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Нотатка"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Показувати значки сповіщень із низьким пріоритетом"</string>
     <string name="other" msgid="429768510980739978">"Інше"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"вилучити опцію"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"додати опцію в кінець"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Перемістити опцію"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Додати панель"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Перемістити на позицію <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додати на позицію <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Позиція недійсна."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"вибрати користувача"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Немає Інтернету"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Відкрити налаштування <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Змінити порядок налаштувань."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню кнопки живлення"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Сторінка <xliff:g id="ID_1">%1$d</xliff:g> з <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Заблокований екран"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(від’єднано)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не вдалося змінити підключення. Натисніть, щоб повторити спробу."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Під’єднати пристрій"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Щоб транслювати цей сеанс, відкрийте додаток."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Невідомий додаток"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Припинити трансляцію"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Доступні пристрої для відтворення звуку."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Перейти на головний екран"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Переглянути нещодавні додатки"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Готово"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Спробуйте ще"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Проведіть трьома пальцями вліво чи вправо по сенсорній панелі"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Чудово!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Ви виконали жест \"Назад\"."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Щоб повернутися за допомогою сенсорної панелі, проведіть трьома пальцями вліво чи вправо"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Перейти на головний екран"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Проведіть трьома пальцями вгору на сенсорній панелі"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Чудово!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Ви виконали жест переходу на головний екран"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Щоб перейти на головний екран, проведіть трьома пальцями вгору на сенсорній панелі"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Переглянути нещодавні додатки"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Проведіть трьома пальцями вгору й утримуйте їх на сенсорній панелі"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Чудово!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Ви виконали жест для перегляду нещодавно відкритих додатків."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Щоб переглянути останні додатки, проведіть трьома пальцями вгору й утримуйте їх на сенсорній панелі"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Переглянути всі додатки"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Натисніть клавішу дії на клавіатурі"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Чудово!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Ви виконали жест для перегляду всіх додатків"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Щоб переглянути всі додатки, натисніть клавішу дії на клавіатурі"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Навчальна анімація. Натисніть, щоб призупинити або відновити відтворення."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Підсвічування клавіатури"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Рівень %1$d з %2$d"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 63213da..28aa1bb 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"اسکرین ریکارڈ سیشن کیلئے جاری اطلاع"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"آپ کی اسکرین ریکارڈ کریں؟"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ایک ایپ ریکارڈ کریں"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"پوری اسکرین کو ریکارڈ کریں"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"‏پوری اسکرین ریکارڈ کریں: ‎%s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"جب آپ اپنی پوری اسکرین کو ریکارڈ کر رہے ہوتے ہیں تو آپ کی اسکرین پر دکھائی گئی ہر چیز ریکارڈ کی جاتی ہے۔ لہذا، پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، تصاویر، ساتھ ہی آڈیو اور ویڈیو جیسی چیزوں کے سلسلے میں محتاط رہیں۔"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"جب آپ کسی ایپ کو ریکارڈ کر رہے ہوتے ہیں تو اس ایپ میں دکھائی گئی یا چلائی گئی ہر چیز ریکارڈ کی جاتی ہے۔ لہذا، پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، تصاویر، ساتھ ہی آڈیو اور ویڈیو جیسی چیزوں کے سلسلے میں محتاط رہیں۔"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"اسکرین ریکارڈ کریں"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"پہلے سے ترتیب شدہ کو اپ ڈیٹ نہیں کیا جا سکا"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"پہلے سے ترتیب شدہ"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"منتخب کردہ"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ٹولز"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"لائیو کیپشن"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"نوٹ"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"کم ترجیحی اطلاع کے آئیکنز دکھائیں"</string>
     <string name="other" msgid="429768510980739978">"دیگر"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"ٹائل ہٹائیں"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ختم کرنے کے لیے ٹائل شامل کریں"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"ٹائل منتقل کریں"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"ٹائل شامل کریں"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"<xliff:g id="POSITION">%1$d</xliff:g> میں منتقل کریں"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"پوزیشن <xliff:g id="POSITION">%1$d</xliff:g> میں شامل کریں"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"پوزیشن غلط ہے۔"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"صارف منتخب کریں"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"انٹرنیٹ نہیں ہے"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> ترتیبات کھولیں۔"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"ترتیبات کی ترتیب میں ترمیم کریں۔"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"پاور مینیو"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"صفحہ <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"مقفل اسکرین"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(غیر منسلک ہے)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"سوئچ نہیں کر سکتے۔ دوبارہ کوشش کرنے کے لیے تھپتھپائیں۔"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"آلہ منسلک کریں"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"اس سیشن کو کاسٹ کرنے کیلئے، براہ کرم ایپ کھولیں۔"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"نامعلوم ایپ"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"کاسٹ کرنا بند کریں"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"آڈیو آؤٹ پٹ کے لیے دستیاب آلات۔"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"ہوم پر جائیں"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"حالیہ ایپس دیکھیں"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"ہو گیا"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"دوبارہ کوشش کریں!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"واپس جائیں"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"اپنے ٹچ پیڈ پر تین انگلیوں کا استعمال کرتے ہوئے دائیں یا بائیں طرف سوائپ کریں"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"عمدہ!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"آپ نے واپس جائیں اشارے کو مکمل کر لیا۔"</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"اپنے ٹچ پیڈ کا استعمال کرتے ہوئے واپس جانے کے لیے، تین انگلیوں کی مدد سے دائیں یا بائیں سوائپ کریں"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"ہوم پر جائیں"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"اپنے ٹچ پیڈ پر تین انگلیوں کی مدد سے اوپر کی طرف سوائپ کریں"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"بہترین!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"آپ نے ہوم پر جانے کا اشارہ مکمل کر لیا"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"اپنی ہوم اسکرین پر جانے کے لیے اپنے ٹچ پیڈ پر تین انگلیوں کی مدد سے اوپر کی طرف سوائپ کریں"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"حالیہ ایپس دیکھیں"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"اپنے ٹچ پیڈ پر تین انگلیوں کا استعمال کرتے ہوئے اوپر کی طرف سوائپ کریں اور دبائے رکھیں"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"بہترین!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"آپ نے حالیہ ایپس دیکھیں کا اشارہ مکمل کر لیا ہے۔"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"حالیہ ایپس دیکھنے کے لیے، اپنے ٹچ پیڈ پر تین انگلیوں کی مدد سے اوپر کی طرف سوائپ کریں اور دبائے رکھیں"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"سبھی ایپس دیکھیں"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"اپنے کی بورڈ پر ایکشن کلید دبائیں"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"بہت خوب!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"آپ نے سبھی ایپس دیکھیں کا اشارہ مکمل کر لیا ہے"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"اپنی سبھی ایپس دیکھنے کے لیے اپنے کی بورڈ پر ایکشن کلید کو دبائیں"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"ٹیوٹوریل اینیمیشن، روکنے کے لیے کلک کریں اور چلانا دوبارہ شروع کریں۔"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"کی بورڈ بیک لائٹ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏%2$d میں سے ‎%1$d کا لیول"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 488852f5..394a6e4 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekrandan yozib olish seansi uchun joriy bildirishnoma"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ekran yozib olinsinmi?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Bitta ilovani yozib olish"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Butun ekranni yozib olish"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Butun ekranni yozib olish: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Butun ekranni yozib olishda ekranda koʻrsatilgan barcha axborotlar yozib olinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Ilovani yozib olishda ilovada koʻrsatilgan yoki ijro etilgan barcha axborotlar yozib olinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekranni yozib olish"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Andoza yangilanmadi"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Andoza"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Tanlangan"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Vositalar"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Jonli izoh"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Qayd"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Muhim boʻlmagan bildirishnoma ikonkalarini koʻrsatish"</string>
     <string name="other" msgid="429768510980739978">"Boshqa"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"katakchani olib tashlash"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"oxiriga katakcha kiritish"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Katakchani boshqa joyga olish"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Katakcha kiritish"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Bu joyga olish: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Bu joyga kiritish: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozitsiya yaroqsiz."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"foydalanuvchini tanlash"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Internetga ulanmagansiz"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> sozlamalarini ochish."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Sozlamalar tartibini o‘zgartirish."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Quvvat menyusi"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>-sahifa, jami: <xliff:g id="ID_2">%2$d</xliff:g> ta sahifa"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekran qulfi"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(uzildi)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Xatolik. Qayta urinish uchun bosing."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Qurilma ulash"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu seansni translatsiya qilish uchun ilovani oching."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Notanish ilova"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Toʻxtatish"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Audio chiqish uchun mavjud qurilmalar."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Boshiga qaytish"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Oxirgi ilovalarni koʻrish"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Tayyor"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Qayta urining!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Orqaga qaytish"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Sensorli panelda uchta barmoq bilan chapga yoki oʻngga suring"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Yaxshi!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Ortga qaytish ishorasi darsini tamomladingiz."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Sensorli panel yordamida orqaga qaytish uchun uchta barmoq bilan chapga yoki oʻngga suring"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Boshiga qaytish"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Sensorli panelda uchta barmoq bilan tepaga suring"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Barakalla!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Bosh ekranni ochish ishorasi darsini tamomladingiz"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Asosiy ekraningizga oʻtish uchun sensorli panelda uchta barmoq bilan suring"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Oxirgi ilovalarni koʻrish"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Sensorli panelda uchta barmoq bilan tepaga surib, bosib turing"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Barakalla!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Oxirgi ilovalarni koʻrish ishorasini tugalladingiz."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Oxirgi ochilgan ilovalarni koʻrish uchun sensorli panelda uchta barmoq bilan tepega surib, ushlab turing"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Barcha ilovalarni koʻrish"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Klaviaturadagi amal tugmasini bosing"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Barakalla!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Hamma ilovalarni koʻrish ishorasini tugalladingiz"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Barcha ilovalaringizni koʻrish uchun klaviaturangizda amal tugmasini bosing"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Qoʻllanma animatsiyasi, pauza qilish va ijroni davom ettirish uchun bosing."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatura orqa yoritkichi"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Daraja: %1$d / %2$d"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 1b505d3d..81ac5e7 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Thông báo đang diễn ra về phiên ghi màn hình"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ghi màn hình?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Ghi một ứng dụng"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Ghi toàn màn hình"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Ghi toàn bộ màn hình: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Khi bạn ghi toàn màn hình, mọi nội dung trên màn hình của bạn đều được ghi. Vì vậy, hãy thận trọng để không làm lộ thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Khi bạn ghi một ứng dụng, mọi nội dung xuất hiện hoặc phát trong ứng dụng đó sẽ đều được ghi. Vì vậy, hãy thận trọng để không làm lộ thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ghi màn hình"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Không cập nhật được giá trị đặt trước"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Chế độ đặt sẵn"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Đã chọn"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Công cụ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Phụ đề trực tiếp"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Ghi chú"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Hiển thị biểu tượng thông báo có mức ưu tiên thấp"</string>
     <string name="other" msgid="429768510980739978">"Khác"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"xóa ô"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"thêm ô vào cuối"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Di chuyển ô"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Thêm ô"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Di chuyển tới <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Thêm vào vị trí <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Vị trí không hợp lệ."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"chọn người dùng"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Không có Internet"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Mở cài đặt <xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Chỉnh sửa thứ tự cài đặt."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Trình đơn nguồn"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Trang <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Màn hình khóa"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(đã ngắt kết nối)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Không thể chuyển đổi. Hãy nhấn để thử lại."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Kết nối thiết bị"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Vui lòng mở ứng dụng để truyền phiên này."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ứng dụng không xác định"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Dừng truyền"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Các thiết bị có sẵn để xuất âm thanh."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Chuyển đến màn hình chính"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Xem các ứng dụng gần đây"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Xong"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Hãy thử lại!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Quay lại"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Dùng 3 ngón tay vuốt sang trái hoặc sang phải trên bàn di chuột"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Tuyệt vời!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Bạn đã thực hiện xong cử chỉ quay lại."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Để quay lại bằng bàn di chuột, hãy dùng 3 ngón tay vuốt sang trái hoặc sang phải"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Chuyển đến màn hình chính"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Dùng 3 ngón tay vuốt lên trên bàn di chuột"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Tuyệt vời!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Bạn đã thực hiện xong cử chỉ chuyển đến màn hình chính"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Dùng 3 ngón tay vuốt lên trên bàn di chuột để chuyển đến màn hình chính"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Xem các ứng dụng gần đây"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Dùng 3 ngón tay vuốt lên và giữ trên bàn di chuột"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Tuyệt vời!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Bạn đã hoàn tất cử chỉ xem ứng dụng gần đây."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Để xem các ứng dụng gần đây, hãy dùng 3 ngón tay vuốt lên và giữ trên bàn di chuột"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Xem tất cả các ứng dụng"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Nhấn phím hành động trên bàn phím"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Rất tốt!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Bạn đã hoàn tất cử chỉ xem tất cả các ứng dụng"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Nhấn phím hành động trên bàn phím để xem mọi ứng dụng của bạn"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Ảnh động trong phần hướng dẫn, nhấp để tạm dừng và tiếp tục phát."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Đèn nền bàn phím"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Độ sáng %1$d/%2$d"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 8d6ec77..1649b3a 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持续显示屏幕录制会话通知"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"要录制屏幕吗?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"录制单个应用"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"录制整个屏幕"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"全屏录制:%s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"录制整个屏幕时,屏幕上显示的所有内容均会被录制。因此,请务必小心操作,谨防泄露密码、付款详情、消息、照片、音频、视频等敏感信息。"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"录制单个应用时,该应用中显示或播放的所有内容均会被录制。因此,请务必小心操作,谨防泄露密码、付款信息、消息、照片、音频、视频等。"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"录制屏幕"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"无法更新预设"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"预设"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"已选择"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"实时字幕"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"记事"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"显示低优先级的通知图标"</string>
     <string name="other" msgid="429768510980739978">"其他"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"移除功能块"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"将功能块添加到末尾"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"移动功能块"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"添加功能块"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"移至 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"添加到位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置无效。"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"选择用户"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"未连接到互联网"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"打开<xliff:g id="ID_1">%s</xliff:g>设置。"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"修改设置顺序。"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"电源菜单"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"第 <xliff:g id="ID_1">%1$d</xliff:g> 页,共 <xliff:g id="ID_2">%2$d</xliff:g> 页"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"锁定屏幕"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(已断开连接)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"无法切换。点按即可重试。"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"连接设备"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如需投放此会话,请打开相关应用。"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"未知应用"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投放"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"音频输出的可用设备。"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"前往主屏幕"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"查看最近用过的应用"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"完成"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"再试一次!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"返回"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"在触控板上用三根手指向左或向右滑动"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"太棒了!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"您已完成“返回”手势教程。"</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"如需使用触控板返回,请用三根手指向左或向右滑动"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"前往主屏幕"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"在触控板上用三根手指向上滑动"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"太棒了!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"您已完成“前往主屏幕”手势"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"在触控板上用三根手指向上滑动,即可前往主屏幕"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"查看最近用过的应用"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"在触控板上用三根手指向上滑动并按住"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"太棒了!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"您已完成“查看最近用过的应用”的手势教程。"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"如需查看最近用过的应用,请用三根手指在触控板上向上滑动并按住"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"查看所有应用"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"按键盘上的快捷操作按键"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"非常棒!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"您已完成“查看所有应用”手势教程"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"按下键盘上的快捷操作按键即可查看所有应用"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"教程动画,点击可暂停和继续播放。"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"键盘背光"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 级,共 %2$d 级"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index b1df372..29e9712 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示錄影畫面工作階段通知"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"要錄影螢幕畫面嗎?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"錄影一個應用程式"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"錄影整個螢幕畫面"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"錄製整個螢幕:%s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"當你錄影整個螢幕畫面時,系統會錄影螢幕畫面上顯示的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片、音訊和影片等。"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"當你錄影應用程式時,系統會錄影該應用程式中顯示或播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片、音訊和影片等。"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"錄影螢幕畫面"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"無法更新預設"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"預設"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"揀咗"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"即時字幕"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"筆記"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"顯示低優先順序通知圖示"</string>
     <string name="other" msgid="429768510980739978">"其他"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"移除圖塊"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"將圖塊加到最尾"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"移動圖塊"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"加圖塊"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"移去 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"加去位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置冇效。"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"揀使用者"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"沒有互聯網連線"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"開啟<xliff:g id="ID_1">%s</xliff:g>設定頁面。"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"編輯設定次序。"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"電源選單"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"第 <xliff:g id="ID_1">%1$d</xliff:g> 頁 (共 <xliff:g id="ID_2">%2$d</xliff:g> 頁)"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"螢幕鎖定"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(已中斷連線)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"無法切換,輕按即可重試。"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"連接裝置"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如要投放此工作階段,請開啟應用程式。"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明應用程式"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投放"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"可用作音訊輸出的裝置"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"返回主畫面"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"查看最近使用的應用程式"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"完成"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"請再試一次!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"返回"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"在觸控板上用三隻手指向左或向右滑動"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"很好!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"你已完成「返回」手勢的教學課程。"</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"如要使用觸控板返回,請用三隻手指向左或向右滑動"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"返回主畫面"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"在觸控板上用三隻手指向上滑動"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"太好了!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"你已完成「返回主畫面」手勢的教學課程"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"用三隻手指在觸控板上向上滑動,即可前往主畫面"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"查看最近使用的應用程式"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"在觸控板上用三隻手指向上滑動並按住"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"做得好!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"你已完成「查看最近使用的應用程式」手勢的教學課程。"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"如要查看最近使用的應用程式,請用三隻手指在觸控板上向上滑動並按住"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"查看所有應用程式"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"按下鍵盤上的快捷操作鍵"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"做得好!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"你已完成「查看所有應用程式」手勢的教學課程"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"按下鍵盤上的快捷操作鍵即可查看所有應用程式"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"教學動畫,按一下以暫停和繼續播放。"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 373f1af..1c80985 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示螢幕畫面錄製工作階段通知"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"要錄製畫面嗎?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"錄製單一應用程式"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"錄製整個畫面"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"錄製整個畫面:%s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"錄製整個畫面時,系統會錄下畫面上的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"當你錄製應用程式畫面時,系統會錄下該應用程式顯示或播放的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"錄製畫面"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"無法更新預設設定"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"預設"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"已選取"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"即時字幕"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"筆記"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"顯示低優先順序通知圖示"</string>
     <string name="other" msgid="429768510980739978">"其他"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"移除圖塊"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"將圖塊加到結尾處"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"移動圖塊"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"新增圖塊"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"移至 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"新增到位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置無效。"</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"選擇使用者"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"沒有網際網路連線"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"開啟「<xliff:g id="ID_1">%s</xliff:g>」設定。"</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"編輯設定順序。"</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"電源鍵選單"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"第 <xliff:g id="ID_1">%1$d</xliff:g> 頁,共 <xliff:g id="ID_2">%2$d</xliff:g> 頁"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"螢幕鎖定"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(連線中斷)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"無法切換,輕觸即可重試。"</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"連接裝置"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如要投放這個工作階段,請開啟應用程式。"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明的應用程式"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投放"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"可用於輸出音訊的裝置。"</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"返回主畫面"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"查看最近使用的應用程式"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"完成"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"請再試一次!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"返回"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"在觸控板上用三指向左或向右滑動"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"很好!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"你已完成「返回」手勢的教學課程。"</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"如要使用觸控板返回,請用三指向左或向右滑動"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"返回主畫面"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"在觸控板上用三指向上滑動"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"太棒了!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"你已完成「返回主畫面」手勢教學課程"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"在觸控板上用三指向上滑動,即可前往主畫面"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"查看最近使用的應用程式"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"在觸控板上用三指向上滑動並按住"</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"太棒了!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"你已完成「查看最近使用的應用程式」手勢教學課程。"</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"如要查看最近使用的應用程式,請在觸控板上用三指向上滑動並按住"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"查看所有應用程式"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"按下鍵盤上的快捷操作鍵"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"非常好!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"你已完成「查看所有應用程式」手勢教學課程"</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"按下鍵盤上的快捷操作鍵即可查看所有應用程式"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"教學課程動畫,按一下即可暫停和繼續播放。"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index a18d9e7..6a8483d 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -111,8 +111,10 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Isaziso esiqhubekayo seseshini yokurekhoda isikrini"</string>
     <string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Rekhoda isikrini sakho?"</string>
     <string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Rekhoda i-app eyodwa"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Rekhoda sonke isikrini"</string>
-    <string name="screenrecord_permission_dialog_option_text_entire_screen_for_display" msgid="3754611651558838691">"Rekhoda sonke isikrini: %s"</string>
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen (4882406311415082016) -->
+    <skip />
+    <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (4169494703993148253) -->
+    <skip />
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Uma urekhoda sonke isikrini sakho, noma yini evela esikrinini iyarekhodwa. Ngakho-ke qaphela ngezinto ezifana namaphasiwedi, imininingwane yenkokhelo, imilayezo, izithombe, nomsindo nevidiyo."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Uma urekhoda i-app, noma yini evezwa noma edlala kuleyo app iyarekhodwa. Ngakho-ke qaphela ngezinto ezifana namaphasiwedi, imininingwane yenkokhelo, imilayezo, izithombe, nomsindo nevidiyo."</string>
     <string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Rekhoda isikrini"</string>
@@ -415,6 +417,20 @@
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ayikwazanga ukubuyekeza ukusetha ngaphambilini"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Ukusetha ngaphambilini"</string>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Okukhethiwe"</string>
+    <!-- no translation found for hearing_devices_ambient_label (629440938614895797) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_left (3586965448230412600) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_control_right (6192137602448918383) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_expand_controls (2131816068187709200) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_collapse_controls (2261097656446201581) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_mute (1836882837647429416) -->
+    <skip />
+    <!-- no translation found for hearing_devices_ambient_unmute (2187938085943876814) -->
+    <skip />
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Amathuluzi"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Okushuthwe Bukhoma"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Inothi"</string>
@@ -960,9 +976,11 @@
     <string name="tuner_low_priority" msgid="8412666814123009820">"Bonisa izithonjana zesaziso zokubaluleka okuncane"</string>
     <string name="other" msgid="429768510980739978">"Okunye"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"susa ithayela"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"engeza ithayela ekugcineni"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_add_action (8311378984458545661) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Hambisa ithayela"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Engeza ithayela"</string>
+    <!-- no translation found for accessibility_qs_edit_tile_start_add (8141710006899065161) -->
+    <skip />
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Hambisa ku-<xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Engeza kusikhundla se-<xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Indawo ayivumelekile."</string>
@@ -978,7 +996,8 @@
     <string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"khetha umsebenzisi"</string>
     <string name="data_connection_no_internet" msgid="691058178914184544">"Ayikho i-inthanethi"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Vula izilungiselelo ze-<xliff:g id="ID_1">%s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Hlela uhlelo lwezilungiselelo."</string>
+    <!-- no translation found for accessibility_quick_settings_edit (6544873823850165) -->
+    <skip />
     <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Imenyu yamandla"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Ikhasi <xliff:g id="ID_1">%1$d</xliff:g> kwangu-<xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Khiya isikrini"</string>
@@ -1209,7 +1228,6 @@
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(inqamukile)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Akukwazi ukushintsha. Thepha ukuze uzame futhi."</string>
     <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Xhuma idivayisi"</string>
-    <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ukuze usakaze le seshini, sicela uvule i-app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"I-app engaziwa"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Misa ukusakaza"</string>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Amadivayisi atholakalayo okukhipha umsindo."</string>
@@ -1468,32 +1486,27 @@
     <string name="touchpad_tutorial_home_gesture_button" msgid="8023973153559885624">"Iya ekhasini lokuqala"</string>
     <string name="touchpad_tutorial_recent_apps_gesture_button" msgid="8919227647650347359">"Buka ama-app akamuva"</string>
     <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Kwenziwe"</string>
-    <!-- no translation found for gesture_error_title (469064941635578511) -->
-    <skip />
+    <string name="gesture_error_title" msgid="469064941635578511">"Zama futhi!"</string>
     <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Buyela emuva"</string>
     <string name="touchpad_back_gesture_guidance" msgid="5352221087725906542">"Swayiphela kwesokunxele noma kwesokudla usebenzisa iminwe emithathu kuphedi yokuthinta"</string>
     <string name="touchpad_back_gesture_success_title" msgid="7370719098633023496">"Kuhle!"</string>
     <string name="touchpad_back_gesture_success_body" msgid="2324724953720741719">"Ukuqedile ukuthinta kokubuyela emuva."</string>
-    <!-- no translation found for touchpad_back_gesture_error_body (7112668207481458792) -->
-    <skip />
+    <string name="touchpad_back_gesture_error_body" msgid="7112668207481458792">"Ukuze ubuyele emuva usebenzise iphedi yakho yokuthinta, swayiphela kwesokunxele noma kwesokudla usebenzisa iminwe emithathu"</string>
     <string name="touchpad_home_gesture_action_title" msgid="8885107349719257882">"Iya ekhasini lokuqala"</string>
     <string name="touchpad_home_gesture_guidance" msgid="4178219118381915899">"Swayiphela phezulu ngeminwe emithathu ephedini yakho yokuthinta"</string>
     <string name="touchpad_home_gesture_success_title" msgid="3648264553645798470">"Umsebenzi omuhle!"</string>
     <string name="touchpad_home_gesture_success_body" msgid="2590690589194027059">"Ukuqedile ukunyakaza kokuya ekhaya"</string>
-    <!-- no translation found for touchpad_home_gesture_error_body (3810674109999513073) -->
-    <skip />
+    <string name="touchpad_home_gesture_error_body" msgid="3810674109999513073">"Swayiphela phezulu ngeminwe emithathu kuphedi yakho yokuthinta ukuze uye esikrinini sakho sasekhaya"</string>
     <string name="touchpad_recent_apps_gesture_action_title" msgid="934906836867137906">"Buka ama-app akamuva"</string>
     <string name="touchpad_recent_apps_gesture_guidance" msgid="6304446013842271822">"Swayiphela phezulu bese ubamba usebenzisa iminwe emithathu ephedini yokuthinta."</string>
     <string name="touchpad_recent_apps_gesture_success_title" msgid="8481920554139332593">"Umsebenzi omuhle!"</string>
     <string name="touchpad_recent_apps_gesture_success_body" msgid="4334263906697493273">"Uqedele ukubuka ukuthinta kwama-app akamuva."</string>
-    <!-- no translation found for touchpad_recent_gesture_error_body (8695535720378462022) -->
-    <skip />
+    <string name="touchpad_recent_gesture_error_body" msgid="8695535720378462022">"Ukuze ubuke ama-app akamuva, swayiphela phezulu futhi ubambe usebenzisa iminwe emithathu kuphedi yakho yokuthinta"</string>
     <string name="tutorial_action_key_title" msgid="8172535792469008169">"Buka wonke ama-app"</string>
     <string name="tutorial_action_key_guidance" msgid="5040613427202799294">"Cindezela inkinobho yokufinyelela kukhibhodi yakho"</string>
     <string name="tutorial_action_key_success_title" msgid="2371827347071979571">"Wenze kahle!"</string>
     <string name="tutorial_action_key_success_body" msgid="1688986269491357832">"Uqedele ukunyakazisa kokubuka onke ama-app."</string>
-    <!-- no translation found for touchpad_action_key_error_body (8685502040091860903) -->
-    <skip />
+    <string name="touchpad_action_key_error_body" msgid="8685502040091860903">"Cindezela inkinobho yokufinyelela kukhibhodi yakho ukuze ubuke wonke ama-app akho"</string>
     <string name="tutorial_animation_content_description" msgid="2698816574982370184">"Okopopayi okokufundisa, chofoza ukuze umise kancane futhi uqalise kabusha ukudlala."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Ilambu lekhibhodi"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Ileveli %1$d ka-%2$d"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index bfaa336..11327b6 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -782,6 +782,13 @@
     <!-- The top margin for the notification children container in its non-expanded form. -->
     <dimen name="notification_children_container_margin_top">48dp</dimen>
 
+    <!-- The spacing between the notification children container in its non-expanded form, and the
+         header text above it, scaling with text size. This value is chosen so that, taking into
+         account the text spacing for both the text in the top line and the text in the container,
+         the distance between them is 4dp with the default screen configuration (and will grow
+         accordingly for larger font sizes). -->
+    <dimen name="notification_2025_children_container_margin_top">@*android:dimen/notification_2025_content_margin_top</dimen>
+
     <!-- The height of the gap between adjacent notification sections. -->
     <dimen name="notification_section_divider_height">@dimen/notification_side_paddings</dimen>
 
@@ -1514,7 +1521,6 @@
     <dimen name="media_output_dialog_header_icon_padding">16dp</dimen>
     <dimen name="media_output_dialog_icon_corner_radius">16dp</dimen>
     <dimen name="media_output_dialog_title_anim_y_delta">12.5dp</dimen>
-    <dimen name="media_output_dialog_app_tier_icon_size">20dp</dimen>
     <dimen name="media_output_dialog_background_radius">16dp</dimen>
     <dimen name="media_output_dialog_active_background_radius">30dp</dimen>
     <dimen name="media_output_dialog_default_margin_end">16dp</dimen>
@@ -2110,6 +2116,8 @@
 
     <dimen name="volume_dialog_background_square_corner_radius">12dp</dimen>
 
+    <dimen name="volume_dialog_ringer_drawer_left_margin">10dp</dimen>
+    <dimen name="volume_dialog_ringer_drawer_diff_right_margin">6dp</dimen>
     <dimen name="volume_dialog_ringer_drawer_button_size">@dimen/volume_dialog_button_size</dimen>
     <dimen name="volume_dialog_ringer_drawer_button_icon_radius">10dp</dimen>
     <dimen name="volume_dialog_ringer_selected_button_background_radius">20dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f14ee14..cd37c22 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -3207,8 +3207,6 @@
     <string name="media_output_dialog_connect_failed">Can\'t switch. Tap to try again.</string>
     <!-- Title for connecting item [CHAR LIMIT=60] -->
     <string name="media_output_dialog_pairing_new">Connect a device</string>
-    <!-- Title for launch app [CHAR LIMIT=60] -->
-    <string name="media_output_dialog_launch_app_text">To cast this session, please open the app.</string>
     <!-- App name when can't get app name [CHAR LIMIT=60] -->
     <string name="media_output_dialog_unknown_launch_app_name">Unknown app</string>
     <!-- Button text for stopping casting [CHAR LIMIT=60] -->
@@ -3369,8 +3367,8 @@
     <!-- Accessibility announcement to inform user to unlock using the fingerprint sensor [CHAR LIMIT=NONE] -->
     <string name="accessibility_fingerprint_bouncer">Authentication required. Touch the fingerprint sensor to authenticate.</string>
 
-    <!-- Content description for a chip in the status bar showing that the user is currently on a phone call. [CHAR LIMIT=NONE] -->
-    <string name="ongoing_phone_call_content_description">Ongoing phone call</string>
+    <!-- Content description for a chip in the status bar showing that the user is currently on a call. [CHAR LIMIT=NONE] -->
+    <string name="ongoing_call_content_description">Ongoing call</string>
 
     <!-- Provider Model: Default title of the mobile network in the mobile layout. [CHAR LIMIT=50] -->
     <string name="mobile_data_settings_title">Mobile data</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 7180678..94698bc 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -73,6 +73,15 @@
     <style name="StatusBar" />
     <style name="StatusBar.Chip" />
 
+    <style name="StatusBar.Chip.RootView">
+        <item name="android:layout_width">wrap_content</item>
+        <!-- Have the root chip view match the parent height so that we get a larger touch area for
+             the chip. -->
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:layout_gravity">center_vertical|start</item>
+        <item name="android:layout_marginStart">5dp</item>
+    </style>
+
     <style name="StatusBar.Chip.Text">
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
@@ -561,6 +570,8 @@
         <item name="trackCornerSize">12dp</item>
         <item name="trackInsideCornerSize">2dp</item>
         <item name="trackStopIndicatorSize">6dp</item>
+        <item name="trackIconSize">20dp</item>
+        <item name="labelBehavior">gone</item>
     </style>
 
     <style name="SystemUI.Material3.Slider" parent="@style/Widget.Material3.Slider">
@@ -570,6 +581,7 @@
         <item name="tickColorInactive">@androidprv:color/materialColorPrimary</item>
         <item name="trackColorActive">@androidprv:color/materialColorPrimary</item>
         <item name="trackColorInactive">@androidprv:color/materialColorSurfaceContainerHighest</item>
+        <item name="trackIconActiveColor">@androidprv:color/materialColorSurfaceContainerHighest</item>
     </style>
 
     <style name="Theme.SystemUI.DayNightDialog" parent="@android:style/Theme.DeviceDefault.Light.Dialog"/>
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
index 41b9d33..5f0acfa 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
@@ -19,6 +19,7 @@
 import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.hardware.display.DisplayManager;
 import android.os.Handler;
@@ -35,6 +36,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
 import com.android.systemui.accessibility.AccessibilityButtonModeObserver.AccessibilityButtonMode;
 import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
@@ -61,6 +63,7 @@
     private final ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager;
     private final DisplayManager mDisplayManager;
     private final AccessibilityManager mAccessibilityManager;
+    private final HearingAidDeviceManager mHearingAidDeviceManager;
 
     private final SecureSettings mSecureSettings;
     private final DisplayTracker mDisplayTracker;
@@ -107,6 +110,7 @@
             AccessibilityManager accessibilityManager,
             AccessibilityButtonTargetsObserver accessibilityButtonTargetsObserver,
             AccessibilityButtonModeObserver accessibilityButtonModeObserver,
+            @Nullable HearingAidDeviceManager hearingAidDeviceManager,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             SecureSettings secureSettings,
             DisplayTracker displayTracker,
@@ -119,6 +123,7 @@
         mAccessibilityManager = accessibilityManager;
         mAccessibilityButtonTargetsObserver = accessibilityButtonTargetsObserver;
         mAccessibilityButtonModeObserver = accessibilityButtonModeObserver;
+        mHearingAidDeviceManager = hearingAidDeviceManager;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mSecureSettings = secureSettings;
         mDisplayTracker = displayTracker;
@@ -201,7 +206,7 @@
                     TYPE_NAVIGATION_BAR_PANEL, /* options= */ null);
             mFloatingMenu = new MenuViewLayerController(windowContext, mWindowManager,
                     mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings,
-                    mNavigationModeController);
+                    mNavigationModeController, mHearingAidDeviceManager);
         }
 
         mFloatingMenu.show();
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java
index ffb5f3d..121b51f 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java
@@ -30,6 +30,7 @@
 
 import android.annotation.FloatRange;
 import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.content.ComponentCallbacks;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
@@ -49,6 +50,8 @@
 
 import com.android.internal.accessibility.dialog.AccessibilityTarget;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
+import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.Prefs;
 import com.android.systemui.util.settings.SecureSettings;
 
@@ -80,8 +83,11 @@
     private final AccessibilityManager mAccessibilityManager;
     private final AccessibilityManager.AccessibilityServicesStateChangeListener
             mA11yServicesStateChangeListener = manager -> onTargetFeaturesChanged();
+    private final HearingAidDeviceManager mHearingAidDeviceManager;
+    private final HearingAidDeviceManager.ConnectionStatusListener
+            mHearingDeviceStatusListener = this::onDevicesConnectionStatusChanged;
     private final Handler mHandler = new Handler(Looper.getMainLooper());
-    private final OnSettingsContentsChanged mSettingsContentsCallback;
+    private final OnContentsChanged mSettingsContentsCallback;
     private final SecureSettings mSecureSettings;
     private Position mPercentagePosition;
 
@@ -148,12 +154,14 @@
     };
 
     MenuInfoRepository(Context context, AccessibilityManager accessibilityManager,
-            OnSettingsContentsChanged settingsContentsChanged, SecureSettings secureSettings) {
+            OnContentsChanged settingsContentsChanged, SecureSettings secureSettings,
+            @Nullable HearingAidDeviceManager hearingAidDeviceManager) {
         mContext = context;
         mAccessibilityManager = accessibilityManager;
         mConfiguration = new Configuration(context.getResources().getConfiguration());
         mSettingsContentsCallback = settingsContentsChanged;
         mSecureSettings = secureSettings;
+        mHearingAidDeviceManager = hearingAidDeviceManager;
 
         mPercentagePosition = getStartPosition();
     }
@@ -185,6 +193,14 @@
         callback.onReady(getTargets(mContext, SOFTWARE));
     }
 
+    void loadHearingDeviceStatus(OnInfoReady<Integer> callback) {
+        if (mHearingAidDeviceManager != null) {
+            callback.onReady(mHearingAidDeviceManager.getDevicesConnectionStatus());
+        } else {
+            callback.onReady(HearingAidDeviceManager.ConnectionStatus.NO_DEVICE_BONDED);
+        }
+    }
+
     void loadMenuSizeType(OnInfoReady<Integer> callback) {
         callback.onReady(getMenuSizeTypeFromSettings());
     }
@@ -222,8 +238,8 @@
     }
 
     private void onTargetFeaturesChanged() {
-        mSettingsContentsCallback.onTargetFeaturesChanged(
-                getTargets(mContext, SOFTWARE));
+        List<AccessibilityTarget> targets = getTargets(mContext, SOFTWARE);
+        mSettingsContentsCallback.onTargetFeaturesChanged(targets);
     }
 
     private Position getStartPosition() {
@@ -269,6 +285,24 @@
             mAccessibilityManager.addAccessibilityServicesStateChangeListener(
                     mA11yServicesStateChangeListener);
         }
+
+        if (com.android.settingslib.flags.Flags.hearingDeviceSetConnectionStatusReport()) {
+            registerConnectionStatusListener();
+        }
+    }
+
+    private void registerConnectionStatusListener() {
+        if (mHearingAidDeviceManager != null) {
+            mHearingAidDeviceManager.registerConnectionStatusListener(
+                    mHearingDeviceStatusListener, ThreadUtils.getBackgroundExecutor());
+        }
+    }
+
+    private void unregisterConnectionStatusListener() {
+        if (mHearingAidDeviceManager != null) {
+            mHearingAidDeviceManager.unregisterConnectionStatusListener(
+                    mHearingDeviceStatusListener);
+        }
     }
 
     void unregisterObserversAndCallbacks() {
@@ -281,14 +315,18 @@
             mAccessibilityManager.removeAccessibilityServicesStateChangeListener(
                     mA11yServicesStateChangeListener);
         }
+
+        unregisterConnectionStatusListener();
     }
 
-    interface OnSettingsContentsChanged {
+    interface OnContentsChanged {
         void onTargetFeaturesChanged(List<AccessibilityTarget> newTargetFeatures);
 
         void onSizeTypeChanged(int newSizeType);
 
         void onFadeEffectInfoChanged(MenuFadeEffectInfo fadeEffectInfo);
+
+        void onDevicesConnectionStatusChanged(@HearingAidDeviceManager.ConnectionStatus int status);
     }
 
     interface OnInfoReady<T> {
@@ -311,4 +349,9 @@
                 ACCESSIBILITY_FLOATING_MENU_OPACITY, DEFAULT_OPACITY_VALUE,
                 UserHandle.USER_CURRENT);
     }
+
+    private void onDevicesConnectionStatusChanged(
+            @HearingAidDeviceManager.ConnectionStatus int status) {
+        mSettingsContentsCallback.onDevicesConnectionStatusChanged(status);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
index 9d9e7df..23fc546 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
@@ -37,6 +37,7 @@
 
 import com.android.internal.accessibility.dialog.AccessibilityTarget;
 import com.android.modules.expresslog.Counter;
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.systemui.Flags;
 import com.android.systemui.util.settings.SecureSettings;
 
@@ -65,8 +66,11 @@
     private final Observer<Integer> mSizeTypeObserver = this::onSizeTypeChanged;
     private final Observer<List<AccessibilityTarget>> mTargetFeaturesObserver =
             this::onTargetFeaturesChanged;
+    private final Observer<Integer> mHearingDeviceStatusObserver =
+            this::updateHearingDeviceStatus;
+    private final Observer<Integer> mHearingDeviceTargetIndexObserver =
+            this::updateHearingDeviceTargetIndex;
     private final MenuViewAppearance mMenuViewAppearance;
-
     private boolean mIsMoveToTucked;
 
     private final MenuAnimationController mMenuAnimationController;
@@ -357,6 +361,11 @@
         mMenuViewModel.getTargetFeaturesData().observeForever(mTargetFeaturesObserver);
         mMenuViewModel.getSizeTypeData().observeForever(mSizeTypeObserver);
         mMenuViewModel.getMoveToTuckedData().observeForever(mMoveToTuckedObserver);
+        if (com.android.settingslib.flags.Flags.hearingDeviceSetConnectionStatusReport()) {
+            mMenuViewModel.loadHearingDeviceStatus().observeForever(mHearingDeviceStatusObserver);
+            mMenuViewModel.getHearingDeviceTargetIndexData().observeForever(
+                    mHearingDeviceTargetIndexObserver);
+        }
         setVisibility(VISIBLE);
         mMenuViewModel.registerObserversAndCallbacks();
         getViewTreeObserver().addOnComputeInternalInsetsListener(this);
@@ -371,6 +380,9 @@
         mMenuViewModel.getTargetFeaturesData().removeObserver(mTargetFeaturesObserver);
         mMenuViewModel.getSizeTypeData().removeObserver(mSizeTypeObserver);
         mMenuViewModel.getMoveToTuckedData().removeObserver(mMoveToTuckedObserver);
+        mMenuViewModel.getHearingDeviceStatusData().removeObserver(mHearingDeviceStatusObserver);
+        mMenuViewModel.getHearingDeviceTargetIndexData().removeObserver(
+                mHearingDeviceTargetIndexObserver);
         mMenuViewModel.unregisterObserversAndCallbacks();
         getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
         getViewTreeObserver().removeOnDrawListener(mSystemGestureExcludeUpdater);
@@ -421,6 +433,14 @@
         parentView.setSystemGestureExclusionRects(Collections.singletonList(mBoundsInParent));
     }
 
+    private void updateHearingDeviceStatus(@HearingAidDeviceManager.ConnectionStatus int status) {
+        // TODO: b/357882387 - To update status drawable according to the status here.
+    }
+
+    private void updateHearingDeviceTargetIndex(int position) {
+        // TODO: b/357882387 - To update status drawable according to the status here.
+    }
+
     /**
      * Interface definition for the {@link AccessibilityTarget} list changes.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java
index cb96e78..184518a 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java
@@ -24,6 +24,7 @@
 import android.view.accessibility.AccessibilityManager;
 
 import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.util.settings.SecureSettings;
 
@@ -39,11 +40,12 @@
     MenuViewLayerController(Context context, WindowManager windowManager,
             ViewCaptureAwareWindowManager viewCaptureAwareWindowManager,
             AccessibilityManager accessibilityManager, SecureSettings secureSettings,
-            NavigationModeController navigationModeController) {
+            NavigationModeController navigationModeController,
+            HearingAidDeviceManager hearingAidDeviceManager) {
         mWindowManager = viewCaptureAwareWindowManager;
 
         MenuViewModel menuViewModel = new MenuViewModel(
-                context, accessibilityManager, secureSettings);
+                context, accessibilityManager, secureSettings, hearingAidDeviceManager);
         MenuViewAppearance menuViewAppearance = new MenuViewAppearance(context, windowManager);
 
         mMenuViewLayer = new MenuViewLayer(context, windowManager, accessibilityManager,
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewModel.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewModel.java
index f924784..8b7d6a1 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewModel.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewModel.java
@@ -16,13 +16,20 @@
 
 package com.android.systemui.accessibility.floatingmenu;
 
+import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
+
+import static java.util.Collections.emptyList;
+
+import android.content.ComponentName;
 import android.content.Context;
 import android.view.accessibility.AccessibilityManager;
 
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.Transformations;
 
 import com.android.internal.accessibility.dialog.AccessibilityTarget;
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.systemui.util.settings.SecureSettings;
 
 import java.util.List;
@@ -31,9 +38,9 @@
  * The view model provides the menu information from the repository{@link MenuInfoRepository} for
  * the menu view{@link MenuView}.
  */
-class MenuViewModel implements MenuInfoRepository.OnSettingsContentsChanged {
+class MenuViewModel implements MenuInfoRepository.OnContentsChanged {
     private final MutableLiveData<List<AccessibilityTarget>> mTargetFeaturesData =
-            new MutableLiveData<>();
+            new MutableLiveData<>(emptyList());
     private final MutableLiveData<Integer> mSizeTypeData = new MutableLiveData<>();
     private final MutableLiveData<MenuFadeEffectInfo> mFadeEffectInfoData =
             new MutableLiveData<>();
@@ -41,12 +48,18 @@
     private final MutableLiveData<Boolean> mDockTooltipData = new MutableLiveData<>();
     private final MutableLiveData<Boolean> mMigrationTooltipData = new MutableLiveData<>();
     private final MutableLiveData<Position> mPercentagePositionData = new MutableLiveData<>();
+    private final MutableLiveData<Integer> mHearingDeviceStatusData = new MutableLiveData<>(
+            HearingAidDeviceManager.ConnectionStatus.NO_DEVICE_BONDED);
+    private final LiveData<Integer> mHearingDeviceTargetIndex = Transformations.map(
+            mTargetFeaturesData, this::getHearingDeviceTargetIndex);
+
     private final MenuInfoRepository mInfoRepository;
 
     MenuViewModel(Context context, AccessibilityManager accessibilityManager,
-            SecureSettings secureSettings) {
+            SecureSettings secureSettings, HearingAidDeviceManager hearingAidDeviceManager) {
         mInfoRepository = new MenuInfoRepository(context,
-                accessibilityManager, /* settingsContentsChanged= */ this, secureSettings);
+                accessibilityManager, /* settingsContentsChanged= */ this, secureSettings,
+                hearingAidDeviceManager);
     }
 
     @Override
@@ -64,6 +77,12 @@
         mFadeEffectInfoData.setValue(fadeEffectInfo);
     }
 
+    @Override
+    public void onDevicesConnectionStatusChanged(
+            @HearingAidDeviceManager.ConnectionStatus int status) {
+        mHearingDeviceStatusData.postValue(status);
+    }
+
     void updateMenuMoveToTucked(boolean isMoveToTucked) {
         mInfoRepository.updateMoveToTucked(isMoveToTucked);
     }
@@ -115,6 +134,19 @@
         return mTargetFeaturesData;
     }
 
+    LiveData<Integer> loadHearingDeviceStatus() {
+        mInfoRepository.loadHearingDeviceStatus(mHearingDeviceStatusData::setValue);
+        return mHearingDeviceStatusData;
+    }
+
+    LiveData<Integer> getHearingDeviceStatusData() {
+        return mHearingDeviceStatusData;
+    }
+
+    LiveData<Integer> getHearingDeviceTargetIndexData() {
+        return mHearingDeviceTargetIndex;
+    }
+
     void registerObserversAndCallbacks() {
         mInfoRepository.registerObserversAndCallbacks();
     }
@@ -122,4 +154,16 @@
     void unregisterObserversAndCallbacks() {
         mInfoRepository.unregisterObserversAndCallbacks();
     }
+
+    private int getHearingDeviceTargetIndex(List<AccessibilityTarget> targetList) {
+        final int listSize = targetList.size();
+        for (int index = 0; index < listSize; index++) {
+            AccessibilityTarget target = targetList.get(index);
+            if (ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.equals(
+                    ComponentName.unflattenFromString(target.getId()))) {
+                return index;
+            }
+        }
+        return -1;
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/AmbientVolumeSlider.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/AmbientVolumeSlider.java
index 92338ef..1a068c4 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/AmbientVolumeSlider.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/AmbientVolumeSlider.java
@@ -45,16 +45,31 @@
             new Slider.OnSliderTouchListener() {
                 @Override
                 public void onStartTrackingTouch(@NonNull Slider slider) {
+                    mTrackingTouch = true;
                 }
 
                 @Override
                 public void onStopTrackingTouch(@NonNull Slider slider) {
+                    mTrackingTouch = false;
                     final int value = Math.round(slider.getValue());
                     for (OnChangeListener listener : mChangeListeners) {
                         listener.onValueChange(AmbientVolumeSlider.this, value);
                     }
                 }
             };
+    private final Slider.OnChangeListener mSliderChangeListener = new Slider.OnChangeListener() {
+        @Override
+        public void onValueChange(@NonNull Slider slider, float value, boolean fromUser) {
+            if (fromUser && !mTrackingTouch) {
+                final int roundedValue = Math.round(value);
+                for (OnChangeListener listener : mChangeListeners) {
+                    listener.onValueChange(AmbientVolumeSlider.this, roundedValue);
+                }
+            }
+        }
+    };
+    private boolean mTrackingTouch = false;
+
     public AmbientVolumeSlider(@Nullable Context context) {
         this(context, /* attrs= */ null);
     }
@@ -76,6 +91,7 @@
         mTitle = requireViewById(R.id.ambient_volume_slider_title);
         mSlider = requireViewById(R.id.ambient_volume_slider);
         mSlider.addOnSliderTouchListener(mSliderTouchListener);
+        mSlider.addOnChangeListener(mSliderChangeListener);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDisplayListener.kt b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDisplayListener.kt
index ca479f5..bee1f74 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDisplayListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDisplayListener.kt
@@ -25,23 +25,25 @@
 import com.android.systemui.biometrics.BiometricDisplayListener.SensorType.Generic
 
 /**
- * A listener for keeping overlays for biometric sensors aligned with the physical device
- * device's screen. The [onChanged] will be dispatched on the [handler]
- * whenever a relevant change to the device's configuration (orientation, fold, display change,
- * etc.) may require the UI to change for the given [sensorType].
+ * A listener for keeping overlays for biometric sensors aligned with the physical device device's
+ * screen. The [onChanged] will be dispatched on the [handler] whenever a relevant change to the
+ * device's configuration (orientation, fold, display change, etc.) may require the UI to change for
+ * the given [sensorType].
  */
 class BiometricDisplayListener(
     private val context: Context,
     private val displayManager: DisplayManager,
     private val handler: Handler,
     private val sensorType: SensorType = SensorType.Generic,
-    private val onChanged: () -> Unit
+    private val onChanged: () -> Unit,
 ) : DisplayManager.DisplayListener {
 
     private var cachedDisplayInfo = DisplayInfo()
 
     override fun onDisplayAdded(displayId: Int) {}
+
     override fun onDisplayRemoved(displayId: Int) {}
+
     override fun onDisplayChanged(displayId: Int) {
         traceSection({ "BiometricDisplayListener($sensorType)#onDisplayChanged" }) {
             val rotationChanged = didRotationChange()
@@ -69,7 +71,7 @@
         displayManager.registerDisplayListener(
             this,
             handler,
-            DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
+            DisplayManager.EVENT_TYPE_DISPLAY_CHANGED,
         )
     }
 
@@ -81,14 +83,15 @@
     /**
      * Type of sensor to determine what kind of display changes require layouts.
      *
-     * The [Generic] type should be used in cases where the modality can vary, such as
-     * biometric prompt (and this object will likely change as multi-mode auth is added).
+     * The [Generic] type should be used in cases where the modality can vary, such as biometric
+     * prompt (and this object will likely change as multi-mode auth is added).
      */
     sealed class SensorType {
         data object Generic : SensorType()
+
         data object UnderDisplayFingerprint : SensorType()
-        data class SideFingerprint(
-            val properties: FingerprintSensorPropertiesInternal
-        ) : SensorType()
+
+        data class SideFingerprint(val properties: FingerprintSensorPropertiesInternal) :
+            SensorType()
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepository.kt b/packages/SystemUI/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepository.kt
index 6c78b8b..e6d6293 100644
--- a/packages/SystemUI/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepository.kt
@@ -133,7 +133,7 @@
                     listener,
                     null,
                     /* eventFlags */ 0,
-                    DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS,
+                    DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS,
                 )
 
                 awaitClose { displayManager.unregisterDisplayListener(listener) }
@@ -181,10 +181,11 @@
             .logDiffForTable(tableBuffer, TABLE_PREFIX_LINEAR, TABLE_COLUMN_BRIGHTNESS, null)
             .stateIn(applicationScope, SharingStarted.WhileSubscribed(), LinearBrightness(0f))
 
-    override val isBrightnessOverriddenByWindow = brightnessInfo
-        .filterNotNull()
-        .map { it.isBrightnessOverrideByWindow }
-        .stateIn(applicationScope, SharingStarted.WhileSubscribed(), false)
+    override val isBrightnessOverriddenByWindow =
+        brightnessInfo
+            .filterNotNull()
+            .map { it.isBrightnessOverrideByWindow }
+            .stateIn(applicationScope, SharingStarted.WhileSubscribed(), false)
 
     override fun setTemporaryBrightness(value: LinearBrightness) {
         apiQueue.trySend(SetBrightnessMethod.Temporary(value))
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/log/CommunalUiEvent.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/log/CommunalUiEvent.kt
index dc322db..3f14252 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/log/CommunalUiEvent.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/log/CommunalUiEvent.kt
@@ -68,7 +68,7 @@
     COMMUNAL_HUB_TO_DREAM_SWIPE_CANCEL(1865),
     @UiEvent(doc = "A transition from Dream to Communal Hub starts due to dream awakening")
     DREAM_TO_COMMUNAL_HUB_DREAM_AWAKE_START(1866),
-    @UiEvent(doc = "User long-pressed the button on Communal Hub to go to Dream")
+    @UiEvent(doc = "User tapped the button on Communal Hub to go to Dream")
     COMMUNAL_HUB_SHOW_DREAM_BUTTON_TAP(2065);
 
     override fun getId(): Int {
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalTutorialIndicatorViewBinder.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalTutorialIndicatorViewBinder.kt
deleted file mode 100644
index 9c754ea..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalTutorialIndicatorViewBinder.kt
+++ /dev/null
@@ -1,51 +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.communal.ui.binder
-
-import android.widget.TextView
-import androidx.core.view.isVisible
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.communal.ui.viewmodel.CommunalTutorialIndicatorViewModel
-import com.android.systemui.lifecycle.repeatWhenAttached
-import kotlinx.coroutines.DisposableHandle
-import com.android.app.tracing.coroutines.launchTraced as launch
-
-/** View binder for communal tutorial indicator shown on keyguard. */
-object CommunalTutorialIndicatorViewBinder {
-    fun bind(
-        view: TextView,
-        viewModel: CommunalTutorialIndicatorViewModel,
-        isPreviewMode: Boolean = false,
-    ): DisposableHandle {
-        val disposableHandle =
-            view.repeatWhenAttached {
-                repeatOnLifecycle(Lifecycle.State.STARTED) {
-                    launch {
-                        viewModel.showIndicator(isPreviewMode).collect { showIndicator ->
-                            view.isVisible = showIndicator
-                        }
-                    }
-
-                    launch { viewModel.alpha.collect { view.alpha = it } }
-                }
-            }
-
-        return disposableHandle
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/CommunalTutorialIndicatorSection.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/CommunalTutorialIndicatorSection.kt
deleted file mode 100644
index 1a323a75..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/CommunalTutorialIndicatorSection.kt
+++ /dev/null
@@ -1,131 +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.communal.ui.view.layout.sections
-
-import android.content.res.Resources
-import android.graphics.Typeface
-import android.graphics.Typeface.NORMAL
-import android.view.Gravity
-import android.view.View
-import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
-import android.widget.TextView
-import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.constraintlayout.widget.ConstraintSet
-import androidx.core.content.res.ResourcesCompat
-import com.android.systemui.communal.domain.interactor.CommunalInteractor
-import com.android.systemui.communal.ui.binder.CommunalTutorialIndicatorViewBinder
-import com.android.systemui.communal.ui.viewmodel.CommunalTutorialIndicatorViewModel
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.keyguard.shared.model.KeyguardSection
-import com.android.systemui.keyguard.ui.view.layout.sections.removeView
-import com.android.systemui.res.R
-import javax.inject.Inject
-import kotlinx.coroutines.DisposableHandle
-
-class CommunalTutorialIndicatorSection
-@Inject
-constructor(
-    @Main private val resources: Resources,
-    private val communalTutorialIndicatorViewModel: CommunalTutorialIndicatorViewModel,
-    private val communalInteractor: CommunalInteractor,
-) : KeyguardSection() {
-    private var communalTutorialIndicatorHandle: DisposableHandle? = null
-
-    override fun addViews(constraintLayout: ConstraintLayout) {
-        if (!communalInteractor.isCommunalEnabled.value) {
-            return
-        }
-        val padding =
-            constraintLayout.resources.getDimensionPixelSize(
-                R.dimen.communal_tutorial_indicator_padding
-            )
-        val view =
-            TextView(constraintLayout.context).apply {
-                id = R.id.communal_tutorial_indicator
-                visibility = View.GONE
-                background =
-                    ResourcesCompat.getDrawable(
-                        context.resources,
-                        R.drawable.keyguard_bottom_affordance_bg,
-                        context.theme
-                    )
-                foreground =
-                    ResourcesCompat.getDrawable(
-                        context.resources,
-                        R.drawable.keyguard_bottom_affordance_selected_border,
-                        context.theme
-                    )
-                gravity = Gravity.CENTER_VERTICAL
-                typeface = Typeface.create("google-sans", NORMAL)
-                text = constraintLayout.context.getString(R.string.communal_tutorial_indicator_text)
-                setPadding(padding, padding, padding, padding)
-            }
-        constraintLayout.addView(view)
-    }
-
-    override fun bindData(constraintLayout: ConstraintLayout) {
-        if (!communalInteractor.isCommunalEnabled.value) {
-            return
-        }
-        communalTutorialIndicatorHandle =
-            CommunalTutorialIndicatorViewBinder.bind(
-                constraintLayout.requireViewById(R.id.communal_tutorial_indicator),
-                communalTutorialIndicatorViewModel,
-            )
-    }
-
-    override fun applyConstraints(constraintSet: ConstraintSet) {
-        if (!communalInteractor.isCommunalEnabled.value) {
-            return
-        }
-        val tutorialIndicatorId = R.id.communal_tutorial_indicator
-        val width = resources.getDimensionPixelSize(R.dimen.communal_tutorial_indicator_fixed_width)
-        val horizontalOffsetMargin =
-            resources.getDimensionPixelSize(R.dimen.communal_tutorial_indicator_horizontal_offset)
-
-        constraintSet.apply {
-            constrainWidth(tutorialIndicatorId, width)
-            constrainHeight(tutorialIndicatorId, WRAP_CONTENT)
-            connect(
-                tutorialIndicatorId,
-                ConstraintSet.RIGHT,
-                ConstraintSet.PARENT_ID,
-                ConstraintSet.RIGHT,
-                horizontalOffsetMargin
-            )
-            connect(
-                tutorialIndicatorId,
-                ConstraintSet.TOP,
-                ConstraintSet.PARENT_ID,
-                ConstraintSet.TOP
-            )
-            connect(
-                tutorialIndicatorId,
-                ConstraintSet.BOTTOM,
-                ConstraintSet.PARENT_ID,
-                ConstraintSet.BOTTOM
-            )
-            setVisibility(tutorialIndicatorId, View.GONE)
-        }
-    }
-
-    override fun removeViews(constraintLayout: ConstraintLayout) {
-        communalTutorialIndicatorHandle?.dispose()
-        constraintLayout.removeView(R.id.communal_tutorial_indicator)
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTutorialIndicatorViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTutorialIndicatorViewModel.kt
deleted file mode 100644
index ce3a2be..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTutorialIndicatorViewModel.kt
+++ /dev/null
@@ -1,47 +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.communal.ui.viewmodel
-
-import com.android.systemui.communal.domain.interactor.CommunalTutorialInteractor
-import javax.inject.Inject
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.flow.flowOf
-
-/** View model for communal tutorial indicator on keyguard */
-class CommunalTutorialIndicatorViewModel
-@Inject
-constructor(private val communalTutorialInteractor: CommunalTutorialInteractor) {
-    /**
-     * An observable for whether the tutorial indicator view should be visible.
-     *
-     * @param isPreviewMode Whether for preview keyguard mode in wallpaper settings.
-     */
-    fun showIndicator(isPreviewMode: Boolean): StateFlow<Boolean> {
-        return if (isPreviewMode) {
-            MutableStateFlow(false).asStateFlow()
-        } else {
-            communalTutorialInteractor.isTutorialAvailable
-        }
-    }
-
-    /** An observable for the alpha level for the tutorial indicator. */
-    // TODO("b/383587536") find replacement for keyguardBottomAreaInteractor alpha
-    val alpha: Flow<Float> = flowOf(0f)
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index ddc4d1c..16cf263 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -33,6 +33,7 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.Logger
 import com.android.systemui.log.dagger.CommunalLog
@@ -92,6 +93,7 @@
     @CommunalLog logBuffer: LogBuffer,
     private val metricsLogger: CommunalMetricsLogger,
     mediaCarouselController: MediaCarouselController,
+    blurConfig: BlurConfig,
 ) :
     BaseCommunalViewModel(
         communalSceneInteractor,
@@ -221,6 +223,15 @@
     val isEnableWorkProfileDialogShowing: Flow<Boolean> =
         _isEnableWorkProfileDialogShowing.asStateFlow()
 
+    val isUiBlurred: StateFlow<Boolean> =
+        if (Flags.bouncerUiRevamp()) {
+            keyguardInteractor.primaryBouncerShowing
+        } else {
+            MutableStateFlow(false)
+        }
+
+    val blurRadiusPx: Float = blurConfig.maxBlurRadiusPx / 2.0f
+
     init {
         // Initialize our media host for the UMO. This only needs to happen once and must be done
         // before the MediaHierarchyManager attempts to move the UMO to the hub.
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SettingsLibraryModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SettingsLibraryModule.java
index 14626e1..e72dfad 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SettingsLibraryModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SettingsLibraryModule.java
@@ -22,6 +22,7 @@
 import android.os.Handler;
 import android.os.UserHandle;
 
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.systemui.dagger.qualifiers.Background;
 
@@ -41,4 +42,16 @@
             @Background Handler bgHandler) {
         return LocalBluetoothManager.create(context, bgHandler, UserHandle.ALL);
     }
+
+    @SuppressLint("MissingPermission")
+    @SysUISingleton
+    @Provides
+    @Nullable
+    static HearingAidDeviceManager provideHearingAidDeviceManager(
+            @Nullable LocalBluetoothManager localBluetoothManager) {
+        if (localBluetoothManager == null) {
+            return null;
+        }
+        return localBluetoothManager.getCachedDeviceManager().getHearingAidDeviceManager();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
index e5acb82..d464200 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
@@ -20,9 +20,9 @@
 import android.hardware.display.DisplayManager
 import android.hardware.display.DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED
 import android.hardware.display.DisplayManager.DisplayListener
-import android.hardware.display.DisplayManager.EVENT_FLAG_DISPLAY_ADDED
-import android.hardware.display.DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
-import android.hardware.display.DisplayManager.EVENT_FLAG_DISPLAY_REMOVED
+import android.hardware.display.DisplayManager.EVENT_TYPE_DISPLAY_ADDED
+import android.hardware.display.DisplayManager.EVENT_TYPE_DISPLAY_CHANGED
+import android.hardware.display.DisplayManager.EVENT_TYPE_DISPLAY_REMOVED
 import android.os.Handler
 import android.util.Log
 import android.view.Display
@@ -147,9 +147,9 @@
                 displayManager.registerDisplayListener(
                     callback,
                     backgroundHandler,
-                    EVENT_FLAG_DISPLAY_ADDED or
-                        EVENT_FLAG_DISPLAY_CHANGED or
-                        EVENT_FLAG_DISPLAY_REMOVED,
+                    EVENT_TYPE_DISPLAY_ADDED or
+                        EVENT_TYPE_DISPLAY_CHANGED or
+                        EVENT_TYPE_DISPLAY_REMOVED,
                 )
                 awaitClose { displayManager.unregisterDisplayListener(callback) }
             }
@@ -279,7 +279,7 @@
                     callback,
                     backgroundHandler,
                     /* eventFlags */ 0,
-                    DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_CONNECTION_CHANGED,
+                    DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_CONNECTION_CHANGED,
                 )
                 awaitClose { displayManager.unregisterDisplayListener(callback) }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt
index f310b30..3390640 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayWindowPropertiesRepository.kt
@@ -18,6 +18,8 @@
 
 import android.annotation.SuppressLint
 import android.content.Context
+import android.os.Bundle
+import android.util.Log
 import android.view.Display
 import android.view.LayoutInflater
 import android.view.WindowManager
@@ -39,14 +41,13 @@
 interface DisplayWindowPropertiesRepository {
 
     /**
-     * Returns a [DisplayWindowProperties] instance for a given display id and window type.
-     *
-     * @throws IllegalArgumentException if no display with the given display id exists.
+     * Returns a [DisplayWindowProperties] instance for a given display id and window type, or null
+     * if no display with the given display id exists.
      */
     fun get(
         displayId: Int,
         @WindowManager.LayoutParams.WindowType windowType: Int,
-    ): DisplayWindowProperties
+    ): DisplayWindowProperties?
 }
 
 @SysUISingleton
@@ -72,12 +73,10 @@
     override fun get(
         displayId: Int,
         @WindowManager.LayoutParams.WindowType windowType: Int,
-    ): DisplayWindowProperties {
-        val display =
-            displayRepository.getDisplay(displayId)
-                ?: throw IllegalArgumentException("Display with id $displayId doesn't exist")
+    ): DisplayWindowProperties? {
+        val display = displayRepository.getDisplay(displayId) ?: return null
         return properties.get(displayId, windowType)
-            ?: create(display, windowType).also { properties.put(displayId, windowType, it) }
+            ?: create(display, windowType)?.also { properties.put(displayId, windowType, it) }
     }
 
     override fun start() {
@@ -88,7 +87,7 @@
         }
     }
 
-    private fun create(display: Display, windowType: Int): DisplayWindowProperties {
+    private fun create(display: Display, windowType: Int): DisplayWindowProperties? {
         val displayId = display.displayId
         return if (displayId == Display.DEFAULT_DISPLAY) {
             // For the default display, we can just reuse the global/application properties.
@@ -102,6 +101,14 @@
             )
         } else {
             val context = createWindowContext(display, windowType)
+            if (context.displayId != display.displayId) {
+                Log.e(
+                    TAG,
+                    "Returning null because the new context doesn't have the desired display id " +
+                        "${display.displayId}. Display was already removed.",
+                )
+                return null
+            }
             @SuppressLint("NonInjectedService") // Need to manually get the service
             val windowManager = context.getSystemService(WindowManager::class.java) as WindowManager
             val layoutInflater = LayoutInflater.from(context)
@@ -110,11 +117,15 @@
     }
 
     private fun createWindowContext(display: Display, windowType: Int): Context =
-        globalContext.createWindowContext(display, windowType, /* options= */ null).also {
+        globalContext.createWindowContext(display, windowType, /* options= */ Bundle.EMPTY).also {
             it.setTheme(R.style.Theme_SystemUI)
         }
 
     override fun dump(pw: PrintWriter, args: Array<out String>) {
         pw.write("perDisplayContexts: $properties")
     }
+
+    private companion object {
+        const val TAG = "DisplayWindowPropsRepo"
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
index 711534f..564588c 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.display.data.repository
 
+import android.util.Log
 import android.view.Display
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.CoreStartable
@@ -36,12 +37,10 @@
     val defaultDisplay: T
 
     /**
-     * Returns an instance for a specific display id.
-     *
-     * @throws IllegalArgumentException if [displayId] doesn't match the id of any existing
-     *   displays.
+     * Returns an instance for a specific display id, or null if [displayId] doesn't match the id of
+     * any existing displays.
      */
-    fun forDisplay(displayId: Int): T
+    fun forDisplay(displayId: Int): T?
 }
 
 abstract class PerDisplayStoreImpl<T>(
@@ -58,7 +57,7 @@
      * Note that the id of the default display is [Display.DEFAULT_DISPLAY].
      */
     override val defaultDisplay: T
-        get() = forDisplay(Display.DEFAULT_DISPLAY)
+        get() = forDisplay(Display.DEFAULT_DISPLAY)!!
 
     /**
      * Returns an instance for a specific display id.
@@ -66,16 +65,30 @@
      * @throws IllegalArgumentException if [displayId] doesn't match the id of any existing
      *   displays.
      */
-    override fun forDisplay(displayId: Int): T {
+    override fun forDisplay(displayId: Int): T? {
         if (displayRepository.getDisplay(displayId) == null) {
-            throw IllegalArgumentException("Display with id $displayId doesn't exist.")
+            Log.e(TAG, "<${instanceClass.simpleName}>: Display with id $displayId doesn't exist.")
+            return null
         }
-        return perDisplayInstances.computeIfAbsent(displayId) {
-            createInstanceForDisplay(displayId)
+        synchronized(perDisplayInstances) {
+            val existingInstance = perDisplayInstances[displayId]
+            if (existingInstance != null) {
+                return existingInstance
+            }
+            val newInstance = createInstanceForDisplay(displayId)
+            if (newInstance == null) {
+                Log.e(
+                    TAG,
+                    "<${instanceClass.simpleName}> returning null because createInstanceForDisplay($displayId) returned null.",
+                )
+            } else {
+                perDisplayInstances[displayId] = newInstance
+            }
+            return newInstance
         }
     }
 
-    protected abstract fun createInstanceForDisplay(displayId: Int): T
+    protected abstract fun createInstanceForDisplay(displayId: Int): T?
 
     override fun start() {
         val instanceType = instanceClass.simpleName
@@ -98,6 +111,10 @@
     override fun dump(pw: PrintWriter, args: Array<out String>) {
         pw.println(perDisplayInstances)
     }
+
+    private companion object {
+        const val TAG = "PerDisplayStore"
+    }
 }
 
 class SingleDisplayStore<T>(defaultInstance: T) : PerDisplayStore<T> {
diff --git a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt
index 22e467b..99c9ca9 100644
--- a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/DisplayWindowPropertiesInteractor.kt
@@ -33,7 +33,7 @@
      *
      * @throws IllegalArgumentException if no display with the given display id exists.
      */
-    fun getForStatusBar(displayId: Int): DisplayWindowProperties
+    fun getForStatusBar(displayId: Int): DisplayWindowProperties?
 }
 
 @SysUISingleton
@@ -42,7 +42,7 @@
 constructor(private val repo: DisplayWindowPropertiesRepository) :
     DisplayWindowPropertiesInteractor {
 
-    override fun getForStatusBar(displayId: Int): DisplayWindowProperties {
+    override fun getForStatusBar(displayId: Int): DisplayWindowProperties? {
         return repo.get(displayId, TYPE_STATUS_BAR)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 2997dd7..c039e01 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -100,10 +100,6 @@
     // TODO(b/242908637): Tracking Bug
     @JvmField val WALLPAPER_FULLSCREEN_PREVIEW = releasedFlag("wallpaper_fullscreen_preview")
 
-    /** Whether the long-press gesture to open wallpaper picker is enabled. */
-    // TODO(b/266242192): Tracking Bug
-    @JvmField val LOCK_SCREEN_LONG_PRESS_ENABLED = releasedFlag("lock_screen_long_press_enabled")
-
     /** Inflate and bind views upon emitting a blueprint value . */
     // TODO(b/297365780): Tracking Bug
     @JvmField val LAZY_INFLATE_KEYGUARD = releasedFlag("lazy_inflate_keyguard")
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
index a901151..284298d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
@@ -18,6 +18,7 @@
 
 import android.animation.ValueAnimator
 import com.android.app.animation.Interpolators
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.Flags.communalSceneKtfRefactor
 import com.android.systemui.Flags.restartDreamOnUnocclude
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
@@ -38,7 +39,6 @@
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 @SysUISingleton
 class FromOccludedTransitionInteractor
@@ -222,6 +222,7 @@
         const val TAG = "FromOccludedTransitionInteractor"
         private val DEFAULT_DURATION = 500.milliseconds
         val TO_ALTERNATE_BOUNCER_DURATION = DEFAULT_DURATION
+        val TO_PRIMARY_BOUNCER_DURATION = DEFAULT_DURATION
         val TO_AOD_DURATION = DEFAULT_DURATION
         val TO_DOZING_DURATION = DEFAULT_DURATION
         val TO_GLANCEABLE_HUB_DURATION = 250.milliseconds
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt
index 274a1dd..a650300 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt
@@ -22,6 +22,7 @@
 import android.content.IntentFilter
 import android.view.accessibility.AccessibilityManager
 import androidx.annotation.VisibleForTesting
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.internal.logging.UiEvent
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.broadcast.BroadcastDispatcher
@@ -29,7 +30,6 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
 import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.data.repository.KeyguardRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.res.R
@@ -51,7 +51,6 @@
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 /** Business logic for use-cases related to top-level touch handling in the lock screen. */
 @OptIn(ExperimentalCoroutinesApi::class)
@@ -121,9 +120,7 @@
     init {
         if (isFeatureEnabled()) {
             broadcastDispatcher
-                .broadcastFlow(
-                    IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS),
-                )
+                .broadcastFlow(IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
                 .onEach { hideMenu() }
                 .launchIn(scope)
         }
@@ -188,8 +185,7 @@
     }
 
     private fun isFeatureEnabled(): Boolean {
-        return featureFlags.isEnabled(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED) &&
-            context.resources.getBoolean(R.bool.long_press_keyguard_customize_lockscreen_enabled)
+        return context.resources.getBoolean(R.bool.long_press_keyguard_customize_lockscreen_enabled)
     }
 
     /** Updates application state to ask to show the menu. */
@@ -230,14 +226,11 @@
             .toLong()
     }
 
-    enum class LogEvents(
-        private val _id: Int,
-    ) : UiEventLogger.UiEventEnum {
+    enum class LogEvents(private val _id: Int) : UiEventLogger.UiEventEnum {
         @UiEvent(doc = "The lock screen was long-pressed and we showed the settings popup menu.")
         LOCK_SCREEN_LONG_PRESS_POPUP_SHOWN(1292),
         @UiEvent(doc = "The lock screen long-press popup menu was clicked.")
-        LOCK_SCREEN_LONG_PRESS_POPUP_CLICKED(1293),
-        ;
+        LOCK_SCREEN_LONG_PRESS_POPUP_CLICKED(1293);
 
         override fun getId() = _id
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
index 1964cb2..d3b76a5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
@@ -84,7 +84,7 @@
                             lastClock = currentClock
                             updateClockAppearance(
                                 currentClock,
-                                clockPreviewConfig.previewContext.resources,
+                                clockPreviewConfig.context.resources,
                             )
 
                             if (viewModel.shouldHighlightSelectedAffordance) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
index 79360370..13c2ffb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
@@ -19,6 +19,8 @@
 
 import android.graphics.Rect
 import android.view.View
+import android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED
+import android.widget.TextView
 import androidx.core.view.isVisible
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
@@ -47,7 +49,7 @@
         touchHandlingViewModel: KeyguardTouchHandlingViewModel,
         rootViewModel: KeyguardRootViewModel?,
         vibratorHelper: VibratorHelper,
-        activityStarter: ActivityStarter
+        activityStarter: ActivityStarter,
     ): DisposableHandle {
         val disposableHandle =
             view.repeatWhenAttached {
@@ -57,19 +59,16 @@
                             view.animateVisibility(visible = isVisible)
                             if (isVisible) {
                                 vibratorHelper.vibrate(KeyguardBottomAreaVibrations.Activated)
+                                val textView = view.requireViewById(R.id.text) as TextView
                                 view.setOnTouchListener(
-                                    KeyguardSettingsButtonOnTouchListener(
-                                        viewModel = viewModel,
-                                    )
+                                    KeyguardSettingsButtonOnTouchListener(viewModel = viewModel)
                                 )
                                 IconViewBinder.bind(
                                     icon = viewModel.icon,
                                     view = view.requireViewById(R.id.icon),
                                 )
-                                TextViewBinder.bind(
-                                    view = view.requireViewById(R.id.text),
-                                    viewModel = viewModel.text,
-                                )
+                                TextViewBinder.bind(view = textView, viewModel = viewModel.text)
+                                textView.sendAccessibilityEvent(TYPE_VIEW_FOCUSED)
                             }
                         }
                     }
@@ -108,15 +107,12 @@
     }
 
     /** Opens the wallpaper picker screen after the device is unlocked by the user. */
-    private fun navigateToLockScreenSettings(
-        activityStarter: ActivityStarter,
-        view: View,
-    ) {
+    private fun navigateToLockScreenSettings(activityStarter: ActivityStarter, view: View) {
         activityStarter.postStartActivityDismissingKeyguard(
             WallpaperPickerIntentUtils.getIntent(view.context, LAUNCH_SOURCE_KEYGUARD),
             /* delay= */ 0,
             /* animationController= */ ActivityTransitionAnimator.Controller.fromView(view),
-            /* customMessage= */ view.context.getString(R.string.keyguard_unlock_to_customize_ls)
+            /* customMessage= */ view.context.getString(R.string.keyguard_unlock_to_customize_ls),
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 6fb31c0..a210787 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -40,7 +40,6 @@
 import android.view.ViewGroup
 import android.view.WindowManager
 import android.widget.FrameLayout
-import android.widget.TextView
 import android.window.InputTransferToken
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.ConstraintSet
@@ -52,8 +51,6 @@
 import com.android.systemui.animation.view.LaunchableImageView
 import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
 import com.android.systemui.broadcast.BroadcastDispatcher
-import com.android.systemui.communal.ui.binder.CommunalTutorialIndicatorViewBinder
-import com.android.systemui.communal.ui.viewmodel.CommunalTutorialIndicatorViewModel
 import com.android.systemui.customization.R as customR
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
@@ -118,7 +115,6 @@
     @Assisted bundle: Bundle,
     private val shadeInteractor: ShadeInteractor,
     private val secureSettings: SecureSettings,
-    private val communalTutorialViewModel: CommunalTutorialIndicatorViewModel,
     private val defaultShortcutsSection: DefaultShortcutsSection,
     private val keyguardQuickAffordanceViewBinder: KeyguardQuickAffordanceViewBinder,
 ) {
@@ -369,7 +365,6 @@
                     ),
             )
         }
-        setupCommunalTutorialIndicator(keyguardRootView)
     }
 
     private fun setupShortcuts(keyguardRootView: ConstraintLayout) {
@@ -487,17 +482,6 @@
         )
     }
 
-    private fun setupCommunalTutorialIndicator(keyguardRootView: ConstraintLayout) {
-        keyguardRootView.findViewById<TextView>(R.id.communal_tutorial_indicator)?.let {
-            indicatorView ->
-            CommunalTutorialIndicatorViewBinder.bind(
-                indicatorView,
-                communalTutorialViewModel,
-                isPreviewMode = true,
-            )
-        }
-    }
-
     @Style.Type
     private suspend fun fetchThemeStyleFromSetting(): Int {
         val overlayPackageJson =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/PrimaryBouncerTransition.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/PrimaryBouncerTransition.kt
index cafc909..4a0817b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/PrimaryBouncerTransition.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/PrimaryBouncerTransition.kt
@@ -16,18 +16,29 @@
 
 package com.android.systemui.keyguard.ui.transitions
 
+import android.content.res.Resources
+import android.util.MathUtils
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToPrimaryBouncerTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.AodToPrimaryBouncerTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.DozingToPrimaryBouncerTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToPrimaryBouncerTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.LockscreenToPrimaryBouncerTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.OccludedToPrimaryBouncerTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToAodTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToDozingTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGlanceableHubTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToLockscreenTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToOccludedTransitionViewModel
+import com.android.systemui.res.R
+import com.android.systemui.window.flag.WindowBlurFlag
 import dagger.Binds
 import dagger.Module
+import dagger.Provides
 import dagger.multibindings.IntoSet
+import javax.inject.Inject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 
@@ -41,9 +52,12 @@
     /** Radius of blur applied to the window's root view. */
     val windowBlurRadius: Flow<Float>
 
-    companion object {
-        const val MAX_BACKGROUND_BLUR_RADIUS = 150f
-        const val MIN_BACKGROUND_BLUR_RADIUS = 0f
+    fun transitionProgressToBlurRadius(
+        starBlurRadius: Float,
+        endBlurRadius: Float,
+        transitionProgress: Float,
+    ): Float {
+        return MathUtils.lerp(starBlurRadius, endBlurRadius, transitionProgress)
     }
 }
 
@@ -76,6 +90,16 @@
 
     @Binds
     @IntoSet
+    fun fromGlanceableHub(
+        impl: GlanceableHubToPrimaryBouncerTransitionViewModel
+    ): PrimaryBouncerTransition
+
+    @Binds
+    @IntoSet
+    fun fromOccluded(impl: OccludedToPrimaryBouncerTransitionViewModel): PrimaryBouncerTransition
+
+    @Binds
+    @IntoSet
     fun toAod(impl: PrimaryBouncerToAodTransitionViewModel): PrimaryBouncerTransition
 
     @Binds
@@ -95,4 +119,30 @@
     @Binds
     @IntoSet
     fun toGone(impl: PrimaryBouncerToGoneTransitionViewModel): PrimaryBouncerTransition
+
+    @Binds
+    @IntoSet
+    fun toOccluded(impl: PrimaryBouncerToOccludedTransitionViewModel): PrimaryBouncerTransition
+
+    companion object {
+        @Provides
+        @SysUISingleton
+        fun provideBlurConfig(@Main resources: Resources): BlurConfig {
+            val minBlurRadius = resources.getDimensionPixelSize(R.dimen.min_window_blur_radius)
+            val maxBlurRadius =
+                if (WindowBlurFlag.isEnabled) {
+                    resources.getDimensionPixelSize(R.dimen.max_shade_window_blur_radius)
+                } else {
+                    resources.getDimensionPixelSize(R.dimen.max_window_blur_radius)
+                }
+            return BlurConfig(minBlurRadius.toFloat(), maxBlurRadius.toFloat())
+        }
+    }
+}
+
+/** Config that provides the max and min blur radius for the window blurs. */
+data class BlurConfig(val minBlurRadiusPx: Float, val maxBlurRadiusPx: Float) {
+    // No-op config that will be used by dagger of other SysUI variants which don't blur the
+    // background surface.
+    @Inject constructor() : this(0.0f, 0.0f)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt
index 6973fec..f34cc07 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt
@@ -17,7 +17,6 @@
 
 package com.android.systemui.keyguard.ui.view.layout.blueprints
 
-import com.android.systemui.communal.ui.view.layout.sections.CommunalTutorialIndicatorSection
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
 import com.android.systemui.keyguard.shared.model.KeyguardSection
@@ -63,7 +62,6 @@
     defaultNotificationStackScrollLayoutSection: DefaultNotificationStackScrollLayoutSection,
     aodNotificationIconsSection: AodNotificationIconsSection,
     aodBurnInSection: AodBurnInSection,
-    communalTutorialIndicatorSection: CommunalTutorialIndicatorSection,
     clockSection: ClockSection,
     smartspaceSection: SmartspaceSection,
     keyguardSliceViewSection: KeyguardSliceViewSection,
@@ -83,7 +81,6 @@
             aodNotificationIconsSection,
             smartspaceSection,
             aodBurnInSection,
-            communalTutorialIndicatorSection,
             clockSection,
             keyguardSliceViewSection,
             defaultDeviceEntrySection,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt
index 1eed224..856e1d6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt
@@ -17,7 +17,6 @@
 
 package com.android.systemui.keyguard.ui.view.layout.blueprints
 
-import com.android.systemui.communal.ui.view.layout.sections.CommunalTutorialIndicatorSection
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
 import com.android.systemui.keyguard.shared.model.KeyguardSection
@@ -61,7 +60,6 @@
     splitShadeGuidelines: SplitShadeGuidelines,
     aodNotificationIconsSection: AodNotificationIconsSection,
     aodBurnInSection: AodBurnInSection,
-    communalTutorialIndicatorSection: CommunalTutorialIndicatorSection,
     clockSection: ClockSection,
     smartspaceSection: SmartspaceSection,
     mediaSection: SplitShadeMediaSection,
@@ -81,7 +79,6 @@
             aodNotificationIconsSection,
             smartspaceSection,
             aodBurnInSection,
-            communalTutorialIndicatorSection,
             clockSection,
             mediaSection,
             defaultDeviceEntrySection, // Add LAST: Intentionally has z-order above other views.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt
index 8af5b5f..f174557 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt
@@ -16,17 +16,15 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
-import android.util.MathUtils
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.domain.interactor.FromAlternateBouncerTransitionInteractor
 import com.android.systemui.keyguard.shared.model.Edge
 import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER
 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MAX_BACKGROUND_BLUR_RADIUS
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MIN_BACKGROUND_BLUR_RADIUS
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.composable.transitions.TO_BOUNCER_FADE_FRACTION
@@ -46,6 +44,7 @@
 @Inject
 constructor(
     animationFlow: KeyguardTransitionAnimationFlow,
+    blurConfig: BlurConfig,
     shadeDependentFlows: ShadeDependentFlows,
 ) : DeviceEntryIconTransition, PrimaryBouncerTransition {
     private val transitionAnimation =
@@ -82,14 +81,18 @@
     override val windowBlurRadius: Flow<Float> =
         shadeDependentFlows.transitionFlow(
             flowWhenShadeIsExpanded =
-                transitionAnimation.immediatelyTransitionTo(MAX_BACKGROUND_BLUR_RADIUS),
+                transitionAnimation.immediatelyTransitionTo(blurConfig.maxBlurRadiusPx),
             flowWhenShadeIsNotExpanded =
                 transitionAnimation.sharedFlow(
                     duration = FromAlternateBouncerTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION,
                     onStep = { step ->
-                        MathUtils.lerp(MIN_BACKGROUND_BLUR_RADIUS, MAX_BACKGROUND_BLUR_RADIUS, step)
+                        transitionProgressToBlurRadius(
+                            starBlurRadius = blurConfig.minBlurRadiusPx,
+                            endBlurRadius = blurConfig.maxBlurRadiusPx,
+                            transitionProgress = step,
+                        )
                     },
-                    onFinish = { MAX_BACKGROUND_BLUR_RADIUS },
+                    onFinish = { blurConfig.maxBlurRadiusPx },
                 ),
         )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModel.kt
index e6b796f..dbb6a49 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModel.kt
@@ -22,9 +22,9 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MAX_BACKGROUND_BLUR_RADIUS
 import com.android.systemui.scene.shared.model.Scenes
 import javax.inject.Inject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -38,7 +38,7 @@
 @SysUISingleton
 class AodToPrimaryBouncerTransitionViewModel
 @Inject
-constructor(animationFlow: KeyguardTransitionAnimationFlow) :
+constructor(blurConfig: BlurConfig, animationFlow: KeyguardTransitionAnimationFlow) :
     DeviceEntryIconTransition, PrimaryBouncerTransition {
     private val transitionAnimation =
         animationFlow
@@ -52,5 +52,5 @@
         transitionAnimation.immediatelyTransitionTo(0f)
 
     override val windowBlurRadius: Flow<Float> =
-        transitionAnimation.immediatelyTransitionTo(MAX_BACKGROUND_BLUR_RADIUS)
+        transitionAnimation.immediatelyTransitionTo(blurConfig.maxBlurRadiusPx)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModel.kt
index c1670c3..d8b617a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModel.kt
@@ -16,17 +16,15 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
-import android.util.MathUtils
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.domain.interactor.FromDozingTransitionInteractor.Companion.TO_PRIMARY_BOUNCER_DURATION
 import com.android.systemui.keyguard.shared.model.Edge
 import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING
 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MAX_BACKGROUND_BLUR_RADIUS
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MIN_BACKGROUND_BLUR_RADIUS
 import com.android.systemui.scene.shared.model.Scenes
 import javax.inject.Inject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -40,7 +38,7 @@
 @SysUISingleton
 class DozingToPrimaryBouncerTransitionViewModel
 @Inject
-constructor(animationFlow: KeyguardTransitionAnimationFlow) :
+constructor(private val blurConfig: BlurConfig, animationFlow: KeyguardTransitionAnimationFlow) :
     DeviceEntryIconTransition, PrimaryBouncerTransition {
 
     private val transitionAnimation =
@@ -58,8 +56,12 @@
         transitionAnimation.sharedFlow(
             TO_PRIMARY_BOUNCER_DURATION,
             onStep = { step ->
-                MathUtils.lerp(MIN_BACKGROUND_BLUR_RADIUS, MAX_BACKGROUND_BLUR_RADIUS, step)
+                transitionProgressToBlurRadius(
+                    starBlurRadius = blurConfig.minBlurRadiusPx,
+                    endBlurRadius = blurConfig.maxBlurRadiusPx,
+                    transitionProgress = step,
+                )
             },
-            onFinish = { MAX_BACKGROUND_BLUR_RADIUS },
+            onFinish = { blurConfig.maxBlurRadiusPx },
         )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModel.kt
new file mode 100644
index 0000000..597df15
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModel.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 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.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor
+import com.android.systemui.keyguard.shared.model.Edge
+import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB
+import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
+import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class GlanceableHubToPrimaryBouncerTransitionViewModel
+@Inject
+constructor(private val blurConfig: BlurConfig, animationFlow: KeyguardTransitionAnimationFlow) :
+    PrimaryBouncerTransition {
+    private val transitionAnimation =
+        animationFlow
+            .setup(
+                duration = FromLockscreenTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION,
+                edge = Edge.INVALID,
+            )
+            .setupWithoutSceneContainer(edge = Edge.create(GLANCEABLE_HUB, PRIMARY_BOUNCER))
+
+    override val windowBlurRadius: Flow<Float> =
+        transitionAnimation.immediatelyTransitionTo(blurConfig.maxBlurRadiusPx)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
index 6e30e48..8fe225a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.keyguard.shared.model.ClockSize
 import com.android.systemui.keyguard.shared.model.ClockSizeSetting
 import com.android.systemui.plugins.clocks.ClockPreviewConfig
-import com.android.systemui.plugins.clocks.DefaultClockFaceLayout.Companion.getSmallClockTopPadding
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -161,15 +160,14 @@
             )
 
     /** Calculates the top margin for the small clock. */
-    fun getSmallClockTopMargin(): Int =
-        getSmallClockTopPadding(
-            ClockPreviewConfig(
+    fun getSmallClockTopMargin(): Int {
+        return ClockPreviewConfig(
                 context,
                 shadeInteractor.isShadeLayoutWide.value,
                 SceneContainerFlag.isEnabled,
-            ),
-            systemBarUtils.getStatusBarHeaderHeightKeyguard(),
-        )
+            )
+            .getSmallClockTopPadding(systemBarUtils.getStatusBarHeaderHeightKeyguard())
+    }
 
     val smallClockTopMargin =
         combine(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
index 15b696e..f6c66d5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
@@ -21,7 +21,6 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.shared.model.ClockSizeSetting
 import com.android.systemui.plugins.clocks.ClockPreviewConfig
-import com.android.systemui.plugins.clocks.DefaultClockFaceLayout.Companion.getSmallClockTopPadding
 import com.android.systemui.statusbar.ui.SystemBarUtilsProxy
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
@@ -74,14 +73,13 @@
      * SmallClockTopPadding decides the top position of smartspace
      */
     fun getSmallClockSmartspaceTopPadding(config: ClockPreviewConfig): Int {
-        return getSmallClockTopPadding(config, systemBarUtils.getStatusBarHeaderHeightKeyguard()) +
-            config.previewContext.resources.getDimensionPixelSize(customR.dimen.small_clock_height)
+        return config.getSmallClockTopPadding(systemBarUtils.getStatusBarHeaderHeightKeyguard()) +
+            config.context.resources.getDimensionPixelSize(customR.dimen.small_clock_height)
     }
 
     fun getLargeClockSmartspaceTopPadding(clockPreviewConfig: ClockPreviewConfig): Int {
-        return getSmallClockTopPadding(
-            clockPreviewConfig,
-            systemBarUtils.getStatusBarHeaderHeightKeyguard(),
+        return clockPreviewConfig.getSmallClockTopPadding(
+            systemBarUtils.getStatusBarHeaderHeightKeyguard()
         )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
index 48cc8ad..c373fd0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
@@ -16,17 +16,15 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
-import android.util.MathUtils
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor
 import com.android.systemui.keyguard.shared.model.Edge
 import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MAX_BACKGROUND_BLUR_RADIUS
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MIN_BACKGROUND_BLUR_RADIUS
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.composable.transitions.TO_BOUNCER_FADE_FRACTION
@@ -44,6 +42,7 @@
 class LockscreenToPrimaryBouncerTransitionViewModel
 @Inject
 constructor(
+    private val blurConfig: BlurConfig,
     shadeDependentFlows: ShadeDependentFlows,
     animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition, PrimaryBouncerTransition {
@@ -85,12 +84,16 @@
     override val windowBlurRadius: Flow<Float> =
         shadeDependentFlows.transitionFlow(
             flowWhenShadeIsExpanded =
-                transitionAnimation.immediatelyTransitionTo(MAX_BACKGROUND_BLUR_RADIUS),
+                transitionAnimation.immediatelyTransitionTo(blurConfig.maxBlurRadiusPx),
             flowWhenShadeIsNotExpanded =
                 transitionAnimation.sharedFlow(
                     duration = FromLockscreenTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION,
                     onStep = {
-                        MathUtils.lerp(MIN_BACKGROUND_BLUR_RADIUS, MAX_BACKGROUND_BLUR_RADIUS, it)
+                        transitionProgressToBlurRadius(
+                            starBlurRadius = blurConfig.minBlurRadiusPx,
+                            endBlurRadius = blurConfig.maxBlurRadiusPx,
+                            transitionProgress = it,
+                        )
                     },
                 ),
         )
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModel.kt
new file mode 100644
index 0000000..4459810
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModel.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 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.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromOccludedTransitionInteractor
+import com.android.systemui.keyguard.shared.model.Edge
+import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
+import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
+import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class OccludedToPrimaryBouncerTransitionViewModel
+@Inject
+constructor(blurConfig: BlurConfig, animationFlow: KeyguardTransitionAnimationFlow) :
+    PrimaryBouncerTransition {
+    private val transitionAnimation =
+        animationFlow
+            .setup(
+                duration = FromOccludedTransitionInteractor.TO_PRIMARY_BOUNCER_DURATION,
+                edge = Edge.INVALID,
+            )
+            .setupWithoutSceneContainer(edge = Edge.create(OCCLUDED, PRIMARY_BOUNCER))
+
+    override val windowBlurRadius: Flow<Float> =
+        transitionAnimation.immediatelyTransitionTo(blurConfig.maxBlurRadiusPx)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt
index f14144e..fab8008 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
-import android.util.MathUtils
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
 import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor
@@ -24,10 +23,9 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MAX_BACKGROUND_BLUR_RADIUS
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MIN_BACKGROUND_BLUR_RADIUS
 import com.android.systemui.scene.shared.model.Scenes
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
@@ -45,6 +43,7 @@
 class PrimaryBouncerToAodTransitionViewModel
 @Inject
 constructor(
+    private val blurConfig: BlurConfig,
     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
     animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition, PrimaryBouncerTransition {
@@ -84,8 +83,12 @@
         transitionAnimation.sharedFlow(
             duration = FromPrimaryBouncerTransitionInteractor.TO_AOD_DURATION,
             onStep = { step ->
-                MathUtils.lerp(MAX_BACKGROUND_BLUR_RADIUS, MIN_BACKGROUND_BLUR_RADIUS, step)
+                transitionProgressToBlurRadius(
+                    starBlurRadius = blurConfig.maxBlurRadiusPx,
+                    endBlurRadius = blurConfig.minBlurRadiusPx,
+                    transitionProgress = step,
+                )
             },
-            onFinish = { MIN_BACKGROUND_BLUR_RADIUS },
+            onFinish = { blurConfig.minBlurRadiusPx },
         )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModel.kt
index a24ed26..eebdf2e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModel.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING
 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
 import com.android.systemui.scene.shared.model.Scenes
@@ -41,6 +42,7 @@
 class PrimaryBouncerToDozingTransitionViewModel
 @Inject
 constructor(
+    private val blurConfig: BlurConfig,
     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
     animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition, PrimaryBouncerTransition {
@@ -67,7 +69,15 @@
         }
 
     override val windowBlurRadius: Flow<Float> =
-        transitionAnimation.immediatelyTransitionTo(
-            PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS
+        transitionAnimation.sharedFlow(
+            duration = TO_DOZING_DURATION,
+            onStep = { step ->
+                transitionProgressToBlurRadius(
+                    starBlurRadius = blurConfig.maxBlurRadiusPx,
+                    endBlurRadius = blurConfig.minBlurRadiusPx,
+                    transitionProgress = step,
+                )
+            },
+            onFinish = { blurConfig.minBlurRadiusPx },
         )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt
index b52a390..3636b74 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt
@@ -22,16 +22,16 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB
 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MIN_BACKGROUND_BLUR_RADIUS
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
 
 @SysUISingleton
 class PrimaryBouncerToGlanceableHubTransitionViewModel
 @Inject
-constructor(animationFlow: KeyguardTransitionAnimationFlow) :
+constructor(private val blurConfig: BlurConfig, animationFlow: KeyguardTransitionAnimationFlow) :
     DeviceEntryIconTransition, PrimaryBouncerTransition {
     private val transitionAnimation =
         animationFlow
@@ -42,5 +42,5 @@
         transitionAnimation.immediatelyTransitionTo(1f)
 
     override val windowBlurRadius: Flow<Float> =
-        transitionAnimation.immediatelyTransitionTo(MIN_BACKGROUND_BLUR_RADIUS)
+        transitionAnimation.immediatelyTransitionTo(blurConfig.minBlurRadiusPx)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
index 713ac15..4ed3e6c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
-import android.util.MathUtils
 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
 import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
 import com.android.systemui.dagger.SysUISingleton
@@ -28,9 +27,8 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
 import com.android.systemui.keyguard.shared.model.ScrimAlpha
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
 import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MAX_BACKGROUND_BLUR_RADIUS
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MIN_BACKGROUND_BLUR_RADIUS
 import com.android.systemui.statusbar.SysuiStatusBarStateController
 import dagger.Lazy
 import javax.inject.Inject
@@ -48,6 +46,7 @@
 class PrimaryBouncerToGoneTransitionViewModel
 @Inject
 constructor(
+    private val blurConfig: BlurConfig,
     private val statusBarStateController: SysuiStatusBarStateController,
     private val primaryBouncerInteractor: PrimaryBouncerInteractor,
     keyguardDismissActionInteractor: Lazy<KeyguardDismissActionInteractor>,
@@ -116,9 +115,13 @@
             onStart = { willRunDismissFromKeyguard = willRunAnimationOnKeyguard() },
             onStep = {
                 if (willRunDismissFromKeyguard) {
-                    MIN_BACKGROUND_BLUR_RADIUS
+                    blurConfig.minBlurRadiusPx
                 } else {
-                    MathUtils.lerp(MAX_BACKGROUND_BLUR_RADIUS, MIN_BACKGROUND_BLUR_RADIUS, it)
+                    transitionProgressToBlurRadius(
+                        starBlurRadius = blurConfig.maxBlurRadiusPx,
+                        endBlurRadius = blurConfig.minBlurRadiusPx,
+                        transitionProgress = it,
+                    )
                 }
             },
         )
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
index e737fce..2edc93cb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
@@ -24,10 +24,9 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MAX_BACKGROUND_BLUR_RADIUS
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition.Companion.MIN_BACKGROUND_BLUR_RADIUS
 import com.android.systemui.scene.shared.model.Scenes
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
@@ -43,6 +42,7 @@
 class PrimaryBouncerToLockscreenTransitionViewModel
 @Inject
 constructor(
+    private val blurConfig: BlurConfig,
     animationFlow: KeyguardTransitionAnimationFlow,
     shadeDependentFlows: ShadeDependentFlows,
 ) : DeviceEntryIconTransition, PrimaryBouncerTransition {
@@ -78,12 +78,16 @@
     override val windowBlurRadius: Flow<Float> =
         shadeDependentFlows.transitionFlow(
             flowWhenShadeIsExpanded =
-                transitionAnimation.immediatelyTransitionTo(MAX_BACKGROUND_BLUR_RADIUS),
+                transitionAnimation.immediatelyTransitionTo(blurConfig.maxBlurRadiusPx),
             flowWhenShadeIsNotExpanded =
                 transitionAnimation.sharedFlow(
                     duration = FromPrimaryBouncerTransitionInteractor.TO_LOCKSCREEN_DURATION,
                     onStep = {
-                        MathUtils.lerp(MAX_BACKGROUND_BLUR_RADIUS, MIN_BACKGROUND_BLUR_RADIUS, it)
+                        transitionProgressToBlurRadius(
+                            starBlurRadius = blurConfig.maxBlurRadiusPx,
+                            endBlurRadius = blurConfig.minBlurRadiusPx,
+                            transitionProgress = it,
+                        )
                     },
                 ),
         )
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModel.kt
new file mode 100644
index 0000000..3a54a26
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModel.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 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.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor
+import com.android.systemui.keyguard.shared.model.Edge
+import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
+import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
+import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class PrimaryBouncerToOccludedTransitionViewModel
+@Inject
+constructor(private val blurConfig: BlurConfig, animationFlow: KeyguardTransitionAnimationFlow) :
+    PrimaryBouncerTransition {
+    private val transitionAnimation =
+        animationFlow
+            .setup(
+                duration = FromPrimaryBouncerTransitionInteractor.TO_OCCLUDED_DURATION,
+                edge = Edge.INVALID,
+            )
+            .setupWithoutSceneContainer(edge = Edge.create(PRIMARY_BOUNCER, OCCLUDED))
+
+    override val windowBlurRadius: Flow<Float> =
+        transitionAnimation.immediatelyTransitionTo(blurConfig.minBlurRadiusPx)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactory.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactory.kt
index 913aa6f..0954482 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactory.kt
@@ -43,6 +43,7 @@
 import com.android.systemui.media.controls.util.SessionTokenFactory
 import com.android.systemui.res.R
 import com.android.systemui.util.concurrency.Execution
+import java.util.concurrent.ExecutionException
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
@@ -71,7 +72,7 @@
      *
      * @param packageName Package name for the media app
      * @param controller The framework [MediaController] for the session
-     * @return The media action buttons, or null if the session token is null
+     * @return The media action buttons, or null if cannot be created for this session
      */
     suspend fun createActionsFromSession(
         packageName: String,
@@ -80,6 +81,10 @@
         // Get the Media3 controller using the legacy token
         val token = tokenFactory.createTokenFromLegacy(sessionToken)
         val m3controller = controllerFactory.create(token, looper)
+        if (m3controller == null) {
+            logger.logCreateFailed(packageName, "createActionsFromSession")
+            return null
+        }
 
         // Build button info
         val buttons = suspendCancellableCoroutine { continuation ->
@@ -89,13 +94,14 @@
                     val result = getMedia3Actions(packageName, m3controller, token)
                     continuation.resumeWith(Result.success(result))
                 } finally {
-                    m3controller.release()
+                    m3controller.tryRelease(packageName, logger)
                 }
             }
             handler.post(runnable)
             continuation.invokeOnCancellation {
                 // Ensure controller is released, even if loading was cancelled partway through
-                handler.post(m3controller::release)
+                val releaseRunnable = Runnable { m3controller.tryRelease(packageName, logger) }
+                handler.post(releaseRunnable)
                 handler.removeCallbacks(runnable)
             }
         }
@@ -127,11 +133,12 @@
                     com.android.internal.R.drawable.progress_small_material,
                 )
             } else {
-                getStandardAction(m3controller, token, Player.COMMAND_PLAY_PAUSE)
+                getStandardAction(packageName, m3controller, token, Player.COMMAND_PLAY_PAUSE)
             }
 
         val prevButton =
             getStandardAction(
+                packageName,
                 m3controller,
                 token,
                 Player.COMMAND_SEEK_TO_PREVIOUS,
@@ -139,6 +146,7 @@
             )
         val nextButton =
             getStandardAction(
+                packageName,
                 m3controller,
                 token,
                 Player.COMMAND_SEEK_TO_NEXT,
@@ -208,6 +216,7 @@
      * @return A [MediaAction] representing the first supported command, or null if not supported
      */
     private fun getStandardAction(
+        packageName: String,
         controller: Media3Controller,
         token: SessionToken,
         vararg commands: @Player.Command Int,
@@ -222,14 +231,14 @@
                     if (!controller.isPlaying) {
                         MediaAction(
                             context.getDrawable(R.drawable.ic_media_play),
-                            { executeAction(token, Player.COMMAND_PLAY_PAUSE) },
+                            { executeAction(packageName, token, Player.COMMAND_PLAY_PAUSE) },
                             context.getString(R.string.controls_media_button_play),
                             context.getDrawable(R.drawable.ic_media_play_container),
                         )
                     } else {
                         MediaAction(
                             context.getDrawable(R.drawable.ic_media_pause),
-                            { executeAction(token, Player.COMMAND_PLAY_PAUSE) },
+                            { executeAction(packageName, token, Player.COMMAND_PLAY_PAUSE) },
                             context.getString(R.string.controls_media_button_pause),
                             context.getDrawable(R.drawable.ic_media_pause_container),
                         )
@@ -238,7 +247,7 @@
                 else -> {
                     MediaAction(
                         icon = getIconForAction(command),
-                        action = { executeAction(token, command) },
+                        action = { executeAction(packageName, token, command) },
                         contentDescription = getDescriptionForAction(command),
                         background = null,
                     )
@@ -256,7 +265,7 @@
     ): MediaAction {
         return MediaAction(
             getIconForAction(customAction, packageName),
-            { executeAction(token, Player.COMMAND_INVALID, customAction) },
+            { executeAction(packageName, token, Player.COMMAND_INVALID, customAction) },
             customAction.displayName,
             null,
         )
@@ -308,12 +317,17 @@
     }
 
     private fun executeAction(
+        packageName: String,
         token: SessionToken,
         command: Int,
         customAction: CommandButton? = null,
     ) {
         bgScope.launch {
             val controller = controllerFactory.create(token, looper)
+            if (controller == null) {
+                logger.logCreateFailed(packageName, "executeAction")
+                return@launch
+            }
             handler.post {
                 try {
                     when (command) {
@@ -347,9 +361,17 @@
                         else -> logger.logMedia3UnsupportedCommand(command.toString())
                     }
                 } finally {
-                    controller.release()
+                    controller.tryRelease(packageName, logger)
                 }
             }
         }
     }
 }
+
+private fun Media3Controller.tryRelease(packageName: String, logger: MediaLogger) {
+    try {
+        this.release()
+    } catch (e: ExecutionException) {
+        logger.logReleaseFailed(packageName, e.cause.toString())
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/shared/MediaLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/MediaLogger.kt
index 0b598c1..c52268e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/shared/MediaLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/MediaLogger.kt
@@ -144,6 +144,30 @@
         buffer.log(TAG, LogLevel.DEBUG, { str1 = command }, { "Unsupported media3 command $str1" })
     }
 
+    fun logCreateFailed(pkg: String, method: String) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = pkg
+                str2 = method
+            },
+            { "Controller create failed for $str1 ($str2)" },
+        )
+    }
+
+    fun logReleaseFailed(pkg: String, cause: String) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = pkg
+                str2 = cause
+            },
+            { "Controller release failed for $str1 ($str2)" },
+        )
+    }
+
     companion object {
         private const val TAG = "MediaLog"
     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControllerFactory.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControllerFactory.kt
index d815852..7b9e18a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControllerFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControllerFactory.kt
@@ -19,13 +19,17 @@
 import android.media.session.MediaController
 import android.media.session.MediaSession
 import android.os.Looper
+import android.util.Log
 import androidx.concurrent.futures.await
 import androidx.media3.session.MediaController as Media3Controller
 import androidx.media3.session.SessionToken
+import java.util.concurrent.ExecutionException
 import javax.inject.Inject
 
 /** Testable wrapper for media controller construction */
 open class MediaControllerFactory @Inject constructor(private val context: Context) {
+    private val TAG = "MediaControllerFactory"
+
     /**
      * Creates a new [MediaController] from the framework session token.
      *
@@ -41,10 +45,18 @@
      * @param token The token for the session
      * @param looper The looper that will be used for this controller's operations
      */
-    open suspend fun create(token: SessionToken, looper: Looper): Media3Controller {
-        return Media3Controller.Builder(context, token)
-            .setApplicationLooper(looper)
-            .buildAsync()
-            .await()
+    open suspend fun create(token: SessionToken, looper: Looper): Media3Controller? {
+        try {
+            return Media3Controller.Builder(context, token)
+                .setApplicationLooper(looper)
+                .buildAsync()
+                .await()
+        } catch (e: ExecutionException) {
+            if (e.cause is SecurityException) {
+                // The session rejected the connection
+                Log.d(TAG, "SecurityException creating media3 controller")
+            }
+            return null
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index 742f435..0ada931 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -98,7 +98,7 @@
                 ((MediaGroupDividerViewHolder) viewHolder).onBind(currentMediaItem.getTitle());
                 break;
             case MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE:
-                ((MediaDeviceViewHolder) viewHolder).onBind(CUSTOMIZED_ITEM_PAIR_NEW);
+                ((MediaDeviceViewHolder) viewHolder).onBindPairNewDevice();
                 break;
             case MediaItem.MediaItemType.TYPE_DEVICE:
                 ((MediaDeviceViewHolder) viewHolder).onBind(
@@ -418,20 +418,18 @@
             updateIconAreaClickListener(listener);
         }
 
-        @Override
-        void onBind(int customizedItem) {
-            if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) {
-                mTitleText.setTextColor(mController.getColorItemContent());
-                mCheckBox.setVisibility(View.GONE);
-                setSingleLineLayout(mContext.getText(R.string.media_output_dialog_pairing_new));
-                final Drawable addDrawable = mContext.getDrawable(R.drawable.ic_add);
-                mTitleIcon.setImageDrawable(addDrawable);
-                mTitleIcon.setImageTintList(
-                        ColorStateList.valueOf(mController.getColorItemContent()));
-                mIconAreaLayout.setBackgroundTintList(
-                        ColorStateList.valueOf(mController.getColorItemBackground()));
-                mContainerLayout.setOnClickListener(mController::launchBluetoothPairing);
-            }
+        /** Binds a ViewHolder for a "Connect a device" item. */
+        void onBindPairNewDevice() {
+            mTitleText.setTextColor(mController.getColorItemContent());
+            mCheckBox.setVisibility(View.GONE);
+            setSingleLineLayout(mContext.getText(R.string.media_output_dialog_pairing_new));
+            final Drawable addDrawable = mContext.getDrawable(R.drawable.ic_add);
+            mTitleIcon.setImageDrawable(addDrawable);
+            mTitleIcon.setImageTintList(
+                    ColorStateList.valueOf(mController.getColorItemContent()));
+            mIconAreaLayout.setBackgroundTintList(
+                    ColorStateList.valueOf(mController.getColorItemBackground()));
+            mContainerLayout.setOnClickListener(mController::launchBluetoothPairing);
         }
 
         private void onGroupActionTriggered(boolean isChecked, MediaDevice device) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index ab998d1..af37eea 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -20,7 +20,6 @@
 
 import android.animation.Animator;
 import android.animation.ValueAnimator;
-import android.annotation.DrawableRes;
 import android.app.WallpaperColors;
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -60,10 +59,6 @@
 public abstract class MediaOutputBaseAdapter extends
         RecyclerView.Adapter<RecyclerView.ViewHolder> {
 
-    static final int CUSTOMIZED_ITEM_PAIR_NEW = 1;
-    static final int CUSTOMIZED_ITEM_GROUP = 2;
-    static final int CUSTOMIZED_ITEM_DYNAMIC_GROUP = 3;
-
     protected final MediaSwitchingController mController;
 
     private static final int UNMUTE_DEFAULT_VOLUME = 2;
@@ -197,8 +192,6 @@
                     ColorStateList.valueOf(mController.getColorSeekbarProgress()));
         }
 
-        abstract void onBind(int customizedItem);
-
         void setSingleLineLayout(CharSequence title) {
             setSingleLineLayout(title, false, false, false, false);
         }
@@ -456,32 +449,6 @@
                     ColorStateList.valueOf(mController.getColorConnectedItemBackground()));
         }
 
-        private void animateCornerAndVolume(int fromProgress, int toProgress) {
-            final GradientDrawable layoutBackgroundDrawable =
-                    (GradientDrawable) mItemLayout.getBackground();
-            final ClipDrawable clipDrawable =
-                    (ClipDrawable) ((LayerDrawable) mSeekBar.getProgressDrawable())
-                            .findDrawableByLayerId(android.R.id.progress);
-            final GradientDrawable targetBackgroundDrawable =
-                    (GradientDrawable) (mIconAreaLayout.getBackground());
-            mCornerAnimator.addUpdateListener(animation -> {
-                float value = (float) animation.getAnimatedValue();
-                layoutBackgroundDrawable.setCornerRadius(value);
-                if (toProgress == 0) {
-                    targetBackgroundDrawable.setCornerRadius(value);
-                } else {
-                    targetBackgroundDrawable.setCornerRadii(new float[]{
-                            value,
-                            value,
-                            0, 0, 0, 0, value, value
-                    });
-                }
-            });
-            mVolumeAnimator.setIntValues(fromProgress, toProgress);
-            mVolumeAnimator.start();
-            mCornerAnimator.start();
-        }
-
         private void initAnimator() {
             mCornerAnimator = ValueAnimator.ofFloat(mController.getInactiveRadius(),
                     mController.getActiveRadius());
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 6bc995f3..64256f9 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -26,13 +26,9 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.ColorFilter;
-import android.graphics.PixelFormat;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
-import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.os.Bundle;
@@ -70,7 +66,6 @@
         implements MediaSwitchingController.Callback, Window.Callback {
 
     private static final String TAG = "MediaOutputDialog";
-    private static final String EMPTY_TITLE = " ";
     private static final String PREF_NAME = "MediaOutputDialog";
     private static final String PREF_IS_LE_BROADCAST_FIRST_LAUNCH = "PrefIsLeBroadcastFirstLaunch";
     private static final boolean DEBUG = true;
@@ -99,11 +94,9 @@
     private ImageView mBroadcastIcon;
     private RecyclerView mDevicesRecyclerView;
     private LinearLayout mDeviceListLayout;
-    private LinearLayout mCastAppLayout;
     private LinearLayout mMediaMetadataSectionLayout;
     private Button mDoneButton;
     private Button mStopButton;
-    private Button mAppButton;
     private int mListMaxHeight;
     private int mItemHeight;
     private int mListPaddingTop;
@@ -262,9 +255,7 @@
         mDeviceListLayout = mDialogView.requireViewById(R.id.device_list);
         mDoneButton = mDialogView.requireViewById(R.id.done);
         mStopButton = mDialogView.requireViewById(R.id.stop);
-        mAppButton = mDialogView.requireViewById(R.id.launch_app_button);
         mAppResourceIcon = mDialogView.requireViewById(R.id.app_source_icon);
-        mCastAppLayout = mDialogView.requireViewById(R.id.cast_app_section);
         mBroadcastIcon = mDialogView.requireViewById(R.id.broadcast_icon);
 
         mDeviceListLayout.getViewTreeObserver().addOnGlobalLayoutListener(
@@ -277,9 +268,11 @@
         // Init bottom buttons
         mDoneButton.setOnClickListener(v -> dismiss());
         mStopButton.setOnClickListener(v -> onStopButtonClick());
-        mAppButton.setOnClickListener(mMediaSwitchingController::tryToLaunchMediaApplication);
-        mMediaMetadataSectionLayout.setOnClickListener(
-                mMediaSwitchingController::tryToLaunchMediaApplication);
+        if (mMediaSwitchingController.getAppLaunchIntent() != null) {
+            // For a11y purposes only add listener if a section is clickable.
+            mMediaMetadataSectionLayout.setOnClickListener(
+                    mMediaSwitchingController::tryToLaunchMediaApplication);
+        }
 
         mDismissing = false;
     }
@@ -333,8 +326,6 @@
         final IconCompat headerIcon = getHeaderIcon();
         final IconCompat appSourceIcon = getAppSourceIcon();
         boolean colorSetUpdated = false;
-        mCastAppLayout.setVisibility(
-                mMediaSwitchingController.shouldShowLaunchSection() ? View.VISIBLE : View.GONE);
         if (iconRes != 0) {
             mHeaderIcon.setVisibility(View.VISIBLE);
             mHeaderIcon.setImageResource(iconRes);
@@ -384,7 +375,6 @@
                     R.dimen.media_output_dialog_header_icon_padding);
             mHeaderIcon.setLayoutParams(new LinearLayout.LayoutParams(size + padding, size));
         }
-        mAppButton.setText(mMediaSwitchingController.getAppSourceName());
 
         if (!mIncludePlaybackAndAppMetadata) {
             mHeaderTitle.setVisibility(View.GONE);
@@ -443,22 +433,6 @@
         mDeviceListLayout.setBackgroundColor(mMediaSwitchingController.getColorDialogBackground());
     }
 
-    private Drawable resizeDrawable(Drawable drawable, int size) {
-        if (drawable == null) {
-            return null;
-        }
-        int width = drawable.getIntrinsicWidth();
-        int height = drawable.getIntrinsicHeight();
-        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
-                : Bitmap.Config.RGB_565;
-        Bitmap bitmap = Bitmap.createBitmap(width, height, config);
-        Canvas canvas = new Canvas(bitmap);
-        drawable.setBounds(0, 0, width, height);
-        drawable.draw(canvas);
-        return new BitmapDrawable(mContext.getResources(),
-                Bitmap.createScaledBitmap(bitmap, size, size, false));
-    }
-
     public void handleLeBroadcastStarted() {
         // Waiting for the onBroadcastMetadataChanged. The UI launchs the broadcast dialog when
         // the metadata is ready.
@@ -602,9 +576,6 @@
         mBroadcastSender.closeSystemDialogs();
     }
 
-    void onHeaderIconClick() {
-    }
-
     View getDialogView() {
         return mDialogView;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java
index 8fbbb8b..1dbb317 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSwitchingController.java
@@ -305,11 +305,6 @@
         }
     }
 
-    boolean shouldShowLaunchSection() {
-        // TODO(b/231398073): Implements this when available.
-        return false;
-    }
-
     public boolean isRefreshing() {
         return mIsRefreshing;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepository.kt b/packages/SystemUI/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepository.kt
index debb667..a19c9b3 100644
--- a/packages/SystemUI/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepository.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.mediarouter.data.repository
 
+import android.media.projection.StopReason
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.log.LogBuffer
@@ -40,7 +41,7 @@
     val castDevices: StateFlow<List<CastDevice>>
 
     /** Stops the cast to the given device. */
-    fun stopCasting(device: CastDevice)
+    fun stopCasting(device: CastDevice, @StopReason stopReason: Int)
 }
 
 @SysUISingleton
@@ -67,8 +68,8 @@
             .map { it.filter { device -> device.origin == CastDevice.CastOrigin.MediaRouter } }
             .stateIn(scope, SharingStarted.WhileSubscribed(), emptyList())
 
-    override fun stopCasting(device: CastDevice) {
-        castController.stopCasting(device)
+    override fun stopCasting(device: CastDevice, @StopReason stopReason: Int) {
+        castController.stopCasting(device, stopReason)
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
index c895732..f9df676 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
@@ -720,9 +720,24 @@
 
         if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mView);
 
-        mViewCaptureAwareWindowManager.addView(mFrame,
-                getBarLayoutParams(mContext.getResources().getConfiguration().windowConfiguration
-                        .getRotation()));
+        try {
+            mViewCaptureAwareWindowManager.addView(
+                    mFrame,
+                    getBarLayoutParams(
+                            mContext.getResources()
+                                    .getConfiguration()
+                                    .windowConfiguration
+                                    .getRotation()));
+        } catch (WindowManager.InvalidDisplayException e) {
+            // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+            // after being added, and initialization hasn't finished yet.
+            Log.e(
+                    TAG,
+                    "Unable to add view to WindowManager. Display with id "
+                            + mDisplayId
+                            + " does not exist anymore",
+                    e);
+        }
         mDisplayId = mContext.getDisplayId();
         mIsOnDefaultDisplay = mDisplayId == mDisplayTracker.getDefaultDisplayId();
 
@@ -764,6 +779,15 @@
             Trace.beginSection("NavigationBar#removeViewImmediate");
             try {
                 mViewCaptureAwareWindowManager.removeViewImmediate(mView.getRootView());
+            } catch (IllegalArgumentException e) {
+                // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+                // after being added, and initialization hasn't finished yet.
+                // When that happens, adding the View to WindowManager fails, and therefore removing
+                // it here will fail too, since it wasn't added in the first place.
+                Log.e(
+                        TAG,
+                        "Failed to removed view from WindowManager. The View wasn't attached.",
+                        e);
             } finally {
                 Trace.endSection();
             }
@@ -859,7 +883,15 @@
         if (mOrientationHandle != null) {
             resetSecondaryHandle();
             getBarTransitions().removeDarkIntensityListener(mOrientationHandleIntensityListener);
-            mViewCaptureAwareWindowManager.removeView(mOrientationHandle);
+            try {
+                mViewCaptureAwareWindowManager.removeView(mOrientationHandle);
+            } catch (IllegalArgumentException e) {
+                // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+                // after being added, and initialization hasn't finished yet.
+                // When that happens, adding the View to WindowManager fails, and therefore removing
+                // it here will fail too, since it wasn't added in the first place.
+                Log.e(TAG, "Trying to remove a View that is not attached", e);
+            }
             mOrientationHandle.getViewTreeObserver().removeOnGlobalLayoutListener(
                     mOrientationHandleGlobalLayoutListener);
         }
@@ -930,7 +962,18 @@
         mOrientationParams.setTitle("SecondaryHomeHandle" + mContext.getDisplayId());
         mOrientationParams.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION
                 | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
-        mViewCaptureAwareWindowManager.addView(mOrientationHandle, mOrientationParams);
+        try {
+            mViewCaptureAwareWindowManager.addView(mOrientationHandle, mOrientationParams);
+        } catch (WindowManager.InvalidDisplayException e) {
+            // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+            // after being added, and initialization hasn't finished yet.
+            Log.e(
+                    TAG,
+                    "Unable to add view to WindowManager. Display with id "
+                            + mDisplayId
+                            + " does not exist anymore",
+                    e);
+        }
         mOrientationHandle.setVisibility(View.GONE);
 
         logNavbarOrientation("initSecondaryHomeHandleForRotation");
diff --git a/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt b/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
index ffeec4e..c302cb2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/flags/QsDetailedView.kt
@@ -79,6 +79,14 @@
     @JvmStatic
     inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
 
+    /**
+     * Called to ensure code is only run when the flag is enabled. This will throw an exception if
+     * the flag is not enabled to ensure that the refactor author catches issues in testing.
+     * Caution!! Using this check incorrectly will cause crashes in nextfood builds!
+     */
+    @JvmStatic
+    inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME)
+
     /** Returns a developer-readable string that describes the current requirement list. */
     @JvmStatic
     fun requirementDescription(): String {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/BounceableInfo.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/BounceableInfo.kt
index b9994d7..c9d767e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/BounceableInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/BounceableInfo.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.qs.panels.ui.compose
 
+import android.processor.immutability.Immutable
 import com.android.compose.animation.Bounceable
 import com.android.systemui.qs.panels.shared.model.SizedTile
 import com.android.systemui.qs.panels.ui.model.GridCell
@@ -23,6 +24,7 @@
 import com.android.systemui.qs.panels.ui.viewmodel.BounceableTileViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
 
+@Immutable
 data class BounceableInfo(
     val bounceable: BounceableTileViewModel,
     val previousTile: Bounceable?,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
index 2928ad1..8fda23d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
@@ -20,6 +20,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.key
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Modifier
@@ -67,17 +68,20 @@
             val it = sizedTiles[spanIndex]
             val column = cellIndex % columns
             cellIndex += it.width
-            Tile(
-                tile = it.tile,
-                iconOnly = it.isIcon,
-                modifier = Modifier.element(it.tile.spec.toElementKey(spanIndex)),
-                squishiness = { squishiness },
-                coroutineScope = scope,
-                bounceableInfo = bounceables.bounceableInfo(it, spanIndex, column, columns),
-                tileHapticsViewModelFactoryProvider = viewModel.tileHapticsViewModelFactoryProvider,
-                // There should be no QuickQuickSettings when the details view is enabled.
-                detailsViewModel = null,
-            )
+            key(it.tile.spec) {
+                Tile(
+                    tile = it.tile,
+                    iconOnly = it.isIcon,
+                    modifier = Modifier.element(it.tile.spec.toElementKey(spanIndex)),
+                    squishiness = { squishiness },
+                    coroutineScope = scope,
+                    bounceableInfo = bounceables.bounceableInfo(it, spanIndex, column, columns),
+                    tileHapticsViewModelFactoryProvider =
+                        viewModel.tileHapticsViewModelFactoryProvider,
+                    // There should be no QuickQuickSettings when the details view is enabled.
+                    detailsViewModel = null,
+                )
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt
index d72d5f1..85658bb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.qs.panels.ui.compose.infinitegrid
 
+import android.content.Context
 import android.graphics.drawable.Animatable
 import android.graphics.drawable.AnimatedVectorDrawable
 import android.graphics.drawable.Drawable
@@ -83,7 +84,7 @@
 fun LargeTileContent(
     label: String,
     secondaryLabel: String?,
-    icon: Icon,
+    iconProvider: Context.() -> Icon,
     sideDrawable: Drawable?,
     colors: TileColors,
     squishiness: () -> Float,
@@ -129,7 +130,7 @@
                 }
         ) {
             SmallTileContent(
-                icon = icon,
+                iconProvider = iconProvider,
                 color = colors.icon,
                 size = { CommonTileDefaults.LargeTileIconSize },
                 modifier = Modifier.align(Alignment.Center),
@@ -194,14 +195,15 @@
 @Composable
 fun SmallTileContent(
     modifier: Modifier = Modifier,
-    icon: Icon,
+    iconProvider: Context.() -> Icon,
     color: Color,
     size: () -> Dp = { CommonTileDefaults.IconSize },
     animateToEnd: Boolean = false,
 ) {
+    val context = LocalContext.current
+    val icon = iconProvider(context)
     val animatedColor by animateColorAsState(color, label = "QSTileIconColor")
     val iconModifier = modifier.size({ size().roundToPx() }, { size().roundToPx() })
-    val context = LocalContext.current
     val loadedDrawable =
         remember(icon, context) {
             when (icon) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
index d975f10..d2ee126 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
@@ -19,7 +19,6 @@
 package com.android.systemui.qs.panels.ui.compose.infinitegrid
 
 import androidx.compose.animation.AnimatedContent
-import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.animation.animateContentSize
 import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.animateDpAsState
@@ -76,6 +75,7 @@
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.key
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
@@ -460,29 +460,34 @@
             Modifier.fillMaxWidth().wrapContentHeight().testTag(AVAILABLE_TILES_GRID_TEST_TAG),
     ) {
         groupedTiles.forEach { (category, tiles) ->
-            Text(
-                text = category.label.load() ?: "",
-                fontSize = 20.sp,
-                color = labelColors.label,
-                modifier = Modifier.fillMaxWidth().padding(start = 16.dp, bottom = 8.dp, top = 8.dp),
-            )
-            tiles.chunked(columns).forEach { row ->
-                Row(
-                    horizontalArrangement = spacedBy(TileArrangementPadding),
-                    modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Max),
-                ) {
-                    row.forEachIndexed { index, tileGridCell ->
-                        AvailableTileGridCell(
-                            cell = tileGridCell,
-                            index = index,
-                            dragAndDropState = dragAndDropState,
-                            selectionState = selectionState,
-                            modifier = Modifier.weight(1f).fillMaxHeight(),
-                        )
-                    }
+            key(category) {
+                Text(
+                    text = category.label.load() ?: "",
+                    fontSize = 20.sp,
+                    color = labelColors.label,
+                    modifier =
+                        Modifier.fillMaxWidth().padding(start = 16.dp, bottom = 8.dp, top = 8.dp),
+                )
+                tiles.chunked(columns).forEach { row ->
+                    Row(
+                        horizontalArrangement = spacedBy(TileArrangementPadding),
+                        modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Max),
+                    ) {
+                        row.forEachIndexed { index, tileGridCell ->
+                            key(tileGridCell.tile.tileSpec) {
+                                AvailableTileGridCell(
+                                    cell = tileGridCell,
+                                    index = index,
+                                    dragAndDropState = dragAndDropState,
+                                    selectionState = selectionState,
+                                    modifier = Modifier.weight(1f).fillMaxHeight(),
+                                )
+                            }
+                        }
 
-                    // Spacers for incomplete rows
-                    repeat(columns - row.size) { Spacer(modifier = Modifier.weight(1f)) }
+                        // Spacers for incomplete rows
+                        repeat(columns - row.size) { Spacer(modifier = Modifier.weight(1f)) }
+                    }
                 }
             }
         }
@@ -711,7 +716,7 @@
         ) {
             // Icon
             SmallTileContent(
-                icon = cell.tile.icon,
+                iconProvider = { cell.tile.icon },
                 color = colors.icon,
                 animateToEnd = true,
                 modifier = Modifier.align(Alignment.Center),
@@ -781,7 +786,7 @@
         // Icon
         Box(Modifier.size(ToggleTargetSize)) {
             SmallTileContent(
-                icon = tile.icon,
+                iconProvider = { tile.icon },
                 color = colors.icon,
                 animateToEnd = true,
                 size = { CommonTileDefaults.IconSize - iconSizeDiff * progress() },
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
index 8fd99a5..66961b6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
@@ -19,6 +19,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.key
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Modifier
@@ -94,16 +95,18 @@
             val it = sizedTiles[spanIndex]
             val column = cellIndex % columns
             cellIndex += it.width
-            Tile(
-                tile = it.tile,
-                iconOnly = iconTilesViewModel.isIconTile(it.tile.spec),
-                modifier = Modifier.element(it.tile.spec.toElementKey(spanIndex)),
-                squishiness = { squishiness },
-                tileHapticsViewModelFactoryProvider = tileHapticsViewModelFactoryProvider,
-                coroutineScope = scope,
-                bounceableInfo = bounceables.bounceableInfo(it, spanIndex, column, columns),
-                detailsViewModel = detailsViewModel,
-            )
+            key(it.tile.spec) {
+                Tile(
+                    tile = it.tile,
+                    iconOnly = iconTilesViewModel.isIconTile(it.tile.spec),
+                    modifier = Modifier.element(it.tile.spec.toElementKey(spanIndex)),
+                    squishiness = { squishiness },
+                    tileHapticsViewModelFactoryProvider = tileHapticsViewModelFactoryProvider,
+                    coroutineScope = scope,
+                    bounceableInfo = bounceables.bounceableInfo(it, spanIndex, column, columns),
+                    detailsViewModel = detailsViewModel,
+                )
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
index 13b3311..47238d1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
@@ -18,6 +18,7 @@
 
 package com.android.systemui.qs.panels.ui.compose.infinitegrid
 
+import android.content.Context
 import android.content.res.Resources
 import android.service.quicksettings.Tile.STATE_ACTIVE
 import android.service.quicksettings.Tile.STATE_INACTIVE
@@ -45,7 +46,10 @@
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.ReadOnlyComposable
+import androidx.compose.runtime.State
+import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.produceState
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberUpdatedState
 import androidx.compose.ui.Alignment
@@ -65,7 +69,6 @@
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.compose.animation.Expandable
 import com.android.compose.animation.bounceable
@@ -90,7 +93,6 @@
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.qs.ui.compose.borderOnFocus
 import com.android.systemui.res.R
-import java.util.function.Supplier
 import kotlinx.coroutines.CoroutineScope
 
 private const val TEST_TAG_SMALL = "qs_tile_small"
@@ -126,10 +128,19 @@
     modifier: Modifier = Modifier,
     detailsViewModel: DetailsViewModel?,
 ) {
-    val state: QSTile.State by tile.state.collectAsStateWithLifecycle(tile.currentState)
     val currentBounceableInfo by rememberUpdatedState(bounceableInfo)
     val resources = resources()
-    val uiState = remember(state, resources) { state.toUiState(resources) }
+
+    /*
+     * Use produce state because [QSTile.State] doesn't have well defined equals (due to
+     * inheritance). This way, even if tile.state changes, uiState may not change and lead to
+     * recomposition.
+     */
+    val uiState by
+        produceState(tile.currentState.toUiState(resources), tile, resources) {
+            tile.state.collect { value = it.toUiState(resources) }
+        }
+
     val colors = TileDefaults.getColorForState(uiState, iconOnly)
     val hapticsViewModel: TileHapticsViewModel? =
         rememberViewModel(traceName = "TileHapticsViewModel") {
@@ -137,7 +148,7 @@
         }
 
     // TODO(b/361789146): Draw the shapes instead of clipping
-    val tileShape = TileDefaults.animateTileShape(uiState.state)
+    val tileShape by TileDefaults.animateTileShapeAsState(uiState.state)
     val animatedColor by animateColorAsState(colors.background, label = "QSTileBackgroundColor")
 
     TileExpandable(
@@ -187,15 +198,15 @@
             uiState = uiState,
             iconOnly = iconOnly,
         ) {
-            val icon = getTileIcon(icon = uiState.icon)
+            val iconProvider: Context.() -> Icon = { getTileIcon(icon = uiState.icon) }
             if (iconOnly) {
                 SmallTileContent(
-                    icon = icon,
+                    iconProvider = iconProvider,
                     color = colors.icon,
                     modifier = Modifier.align(Alignment.Center),
                 )
             } else {
-                val iconShape = TileDefaults.animateIconShape(uiState.state)
+                val iconShape by TileDefaults.animateIconShapeAsState(uiState.state)
                 val secondaryClick: (() -> Unit)? =
                     {
                             hapticsViewModel?.setTileInteractionState(
@@ -207,7 +218,7 @@
                 LargeTileContent(
                     label = uiState.label,
                     secondaryLabel = uiState.secondaryLabel,
-                    icon = icon,
+                    iconProvider = iconProvider,
                     sideDrawable = uiState.sideDrawable,
                     colors = colors,
                     iconShape = iconShape,
@@ -269,7 +280,7 @@
 
     Box(
         modifier
-            .clip(TileDefaults.animateTileShape(state = uiState.state))
+            .clip(TileDefaults.animateTileShapeAsState(state = uiState.state).value)
             .background(colors.background)
             .height(TileHeight)
             .tilePadding()
@@ -277,7 +288,7 @@
         LargeTileContent(
             label = uiState.label,
             secondaryLabel = "",
-            icon = getTileIcon(icon = uiState.icon),
+            iconProvider = { getTileIcon(icon = uiState.icon) },
             sideDrawable = null,
             colors = colors,
             squishiness = { 1f },
@@ -285,14 +296,12 @@
     }
 }
 
-@Composable
-private fun getTileIcon(icon: Supplier<QSTile.Icon?>): Icon {
-    val context = LocalContext.current
-    return icon.get()?.let {
+private fun Context.getTileIcon(icon: QSTile.Icon?): Icon {
+    return icon?.let {
         if (it is QSTileImpl.ResourceIcon) {
             Icon.Resource(it.resId, null)
         } else {
-            Icon.Loaded(it.getDrawable(context), null)
+            Icon.Loaded(it.getDrawable(this), null)
         }
     } ?: Icon.Resource(R.drawable.ic_error_outline, null)
 }
@@ -348,6 +357,7 @@
 
     /** An active tile without dual target uses the active color as background */
     @Composable
+    @ReadOnlyComposable
     fun activeTileColors(): TileColors =
         TileColors(
             background = MaterialTheme.colorScheme.primary,
@@ -359,6 +369,7 @@
 
     /** An active tile with dual target only show the active color on the icon */
     @Composable
+    @ReadOnlyComposable
     fun activeDualTargetTileColors(): TileColors =
         TileColors(
             background = MaterialTheme.colorScheme.surfaceVariant,
@@ -369,6 +380,7 @@
         )
 
     @Composable
+    @ReadOnlyComposable
     fun inactiveDualTargetTileColors(): TileColors =
         TileColors(
             background = MaterialTheme.colorScheme.surfaceVariant,
@@ -379,6 +391,7 @@
         )
 
     @Composable
+    @ReadOnlyComposable
     fun inactiveTileColors(): TileColors =
         TileColors(
             background = MaterialTheme.colorScheme.surfaceVariant,
@@ -389,6 +402,7 @@
         )
 
     @Composable
+    @ReadOnlyComposable
     fun unavailableTileColors(): TileColors =
         TileColors(
             background = MaterialTheme.colorScheme.surface,
@@ -399,6 +413,7 @@
         )
 
     @Composable
+    @ReadOnlyComposable
     fun getColorForState(uiState: TileUiState, iconOnly: Boolean): TileColors {
         return when (uiState.state) {
             STATE_ACTIVE -> {
@@ -422,8 +437,8 @@
     }
 
     @Composable
-    fun animateIconShape(state: Int): RoundedCornerShape {
-        return animateShape(
+    fun animateIconShapeAsState(state: Int): State<RoundedCornerShape> {
+        return animateShapeAsState(
             state = state,
             activeCornerRadius = ActiveIconCornerRadius,
             label = "QSTileCornerRadius",
@@ -431,8 +446,8 @@
     }
 
     @Composable
-    fun animateTileShape(state: Int): RoundedCornerShape {
-        return animateShape(
+    fun animateTileShapeAsState(state: Int): State<RoundedCornerShape> {
+        return animateShapeAsState(
             state = state,
             activeCornerRadius = ActiveTileCornerRadius,
             label = "QSTileIconCornerRadius",
@@ -440,7 +455,11 @@
     }
 
     @Composable
-    fun animateShape(state: Int, activeCornerRadius: Dp, label: String): RoundedCornerShape {
+    fun animateShapeAsState(
+        state: Int,
+        activeCornerRadius: Dp,
+        label: String,
+    ): State<RoundedCornerShape> {
         val animatedCornerRadius by
             animateDpAsState(
                 targetValue =
@@ -459,7 +478,7 @@
                 }
             }
         }
-        return RoundedCornerShape(corner)
+        return remember { derivedStateOf { RoundedCornerShape(corner) } }
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt
index 2fc7f0f..19e542e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.qs.tileimpl.SubtitleArrayMapping
 import com.android.systemui.res.R
-import java.util.function.Supplier
 
 @Immutable
 data class TileUiState(
@@ -36,7 +35,7 @@
     val state: Int,
     val handlesLongClick: Boolean,
     val handlesSecondaryClick: Boolean,
-    val icon: Supplier<QSTile.Icon?>,
+    val icon: QSTile.Icon?,
     val sideDrawable: Drawable?,
     val accessibilityUiState: AccessibilityUiState,
 )
@@ -91,7 +90,7 @@
         state = if (disabledByPolicy) Tile.STATE_UNAVAILABLE else state,
         handlesLongClick = handlesLongClick,
         handlesSecondaryClick = handlesSecondaryClick,
-        icon = icon?.let { Supplier { icon } } ?: iconSupplier ?: Supplier { null },
+        icon = icon ?: iconSupplier?.get(),
         sideDrawable = sideViewCustomDrawable,
         AccessibilityUiState(
             contentDescription?.toString() ?: "",
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/startable/QSPipelineCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/startable/QSPipelineCoreStartable.kt
index 9677d47..3b3fb9b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/startable/QSPipelineCoreStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/startable/QSPipelineCoreStartable.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
 import com.android.systemui.qs.pipeline.domain.interactor.RestoreReconciliationInteractor
 import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository
+import com.android.systemui.qs.shared.QSSettingsPackageRepository
 import javax.inject.Inject
 
 @SysUISingleton
@@ -33,12 +34,14 @@
     private val accessibilityTilesInteractor: AccessibilityTilesInteractor,
     private val autoAddInteractor: AutoAddInteractor,
     private val featureFlags: QSPipelineFlagsRepository,
+    private val settingsPackageRepository: QSSettingsPackageRepository,
     private val restoreReconciliationInteractor: RestoreReconciliationInteractor,
 ) : CoreStartable {
 
     override fun start() {
         accessibilityTilesInteractor.init(currentTilesInteractor)
         autoAddInteractor.init(currentTilesInteractor)
+        settingsPackageRepository.init()
         restoreReconciliationInteractor.start()
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/shared/QSSettingsPackageRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/shared/QSSettingsPackageRepository.kt
new file mode 100644
index 0000000..592e9da
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/shared/QSSettingsPackageRepository.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2024 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.qs.shared
+
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.os.UserHandle
+import android.provider.Settings
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.user.data.repository.UserRepository
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+/**
+ * Provides the cached package name of the default Settings application.
+ *
+ * This repository retrieves and stores the package name to avoid repeated lookups. The package name
+ * is retrieved in a background thread when the `init()` method is called.
+ */
+@SysUISingleton
+@Suppress("ShadeDisplayAwareContextChecker")
+class QSSettingsPackageRepository
+@Inject
+constructor(
+    private val context: Context,
+    @Background private val backgroundScope: CoroutineScope,
+    private val userRepository: UserRepository,
+) {
+    private var settingsPackageName: String? = null
+
+    /**
+     * Initializes the repository by determining and caching the package name of the Settings app.
+     */
+    fun init() {
+        backgroundScope.launch {
+            val mainUserId = userRepository.mainUserId
+            val mainUserContext =
+                context.createContextAsUser(UserHandle.of(mainUserId), /* flags */ 0)
+            val pm = mainUserContext.packageManager
+            settingsPackageName =
+                pm.queryIntentActivities(
+                        Intent(Settings.ACTION_SETTINGS),
+                        PackageManager.MATCH_SYSTEM_ONLY or PackageManager.MATCH_DEFAULT_ONLY,
+                    )
+                    .firstOrNull()
+                    ?.activityInfo
+                    ?.packageName ?: DEFAULT_SETTINGS_PACKAGE_NAME
+        }
+    }
+
+    /**
+     * Returns the cached package name of the Settings app.
+     *
+     * If the package name has not been initialized yet, this method will return the default
+     * Settings package name.
+     *
+     * @return The package name of the Settings app.
+     */
+    fun getSettingsPackageName(): String {
+        return settingsPackageName ?: DEFAULT_SETTINGS_PACKAGE_NAME
+    }
+
+    companion object {
+        private const val DEFAULT_SETTINGS_PACKAGE_NAME = "com.android.settings"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index ad027b4..30c2adf 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -24,6 +24,7 @@
 import android.app.Dialog;
 import android.content.Intent;
 import android.media.MediaRouter.RouteInfo;
+import android.media.projection.StopReason;
 import android.os.Handler;
 import android.os.Looper;
 import android.provider.Settings;
@@ -183,7 +184,7 @@
                 });
             }
         } else {
-            mController.stopCasting(activeDevices.get(0));
+            mController.stopCasting(activeDevices.get(0), StopReason.STOP_QS_TILE);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java
index c2e609d..1f93681 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorCorrectionTile.java
@@ -38,6 +38,7 @@
 import com.android.systemui.qs.QsEventLogger;
 import com.android.systemui.qs.UserSettingObserver;
 import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.shared.QSSettingsPackageRepository;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.res.R;
 import com.android.systemui.settings.UserTracker;
@@ -53,6 +54,7 @@
     @Nullable
     private Icon mIcon = null;
     private final UserSettingObserver mSetting;
+    private final QSSettingsPackageRepository mQSSettingsPackageRepository;
 
     @Inject
     public ColorCorrectionTile(
@@ -66,11 +68,13 @@
             ActivityStarter activityStarter,
             QSLogger qsLogger,
             UserTracker userTracker,
-            SecureSettings secureSettings
+            SecureSettings secureSettings,
+            QSSettingsPackageRepository qsSettingsPackageRepository
     ) {
         super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger,
                 statusBarStateController, activityStarter, qsLogger);
 
+        mQSSettingsPackageRepository = qsSettingsPackageRepository;
         mSetting = new UserSettingObserver(secureSettings, mHandler,
                 Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, userTracker.getUserId()) {
             @Override
@@ -106,7 +110,8 @@
 
     @Override
     public Intent getLongClickIntent() {
-        return new Intent(Settings.ACTION_COLOR_CORRECTION_SETTINGS);
+        return new Intent(Settings.ACTION_COLOR_CORRECTION_SETTINGS)
+                .setPackage(mQSSettingsPackageRepository.getSettingsPackageName());
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index ce80133..38e9a20 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -39,6 +39,7 @@
 import com.android.systemui.qs.QsEventLogger;
 import com.android.systemui.qs.UserSettingObserver;
 import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.shared.QSSettingsPackageRepository;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.res.R;
 import com.android.systemui.settings.UserTracker;
@@ -51,6 +52,7 @@
 
     public static final String TILE_SPEC = "inversion";
     private final UserSettingObserver mSetting;
+    private final QSSettingsPackageRepository mQSSettingsPackageRepository;
 
     @Inject
     public ColorInversionTile(
@@ -64,11 +66,13 @@
             ActivityStarter activityStarter,
             QSLogger qsLogger,
             UserTracker userTracker,
-            SecureSettings secureSettings
+            SecureSettings secureSettings,
+            QSSettingsPackageRepository qsSettingsPackageRepository
     ) {
         super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger,
                 statusBarStateController, activityStarter, qsLogger);
 
+        mQSSettingsPackageRepository = qsSettingsPackageRepository;
         mSetting = new UserSettingObserver(secureSettings, mHandler,
                 Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, userTracker.getUserId()) {
             @Override
@@ -104,7 +108,8 @@
 
     @Override
     public Intent getLongClickIntent() {
-        return new Intent(Settings.ACTION_COLOR_INVERSION_SETTINGS);
+        return new Intent(Settings.ACTION_COLOR_INVERSION_SETTINGS)
+                .setPackage(mQSSettingsPackageRepository.getSettingsPackageName());
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt
index 43e84a0..4050f2a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt
@@ -34,6 +34,7 @@
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
 import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.shared.QSSettingsPackageRepository
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.phone.SystemUIDialog
@@ -56,6 +57,7 @@
     private val keyguardStateController: KeyguardStateController,
     private val dialogTransitionAnimator: DialogTransitionAnimator,
     private val fontScalingDialogDelegateProvider: Provider<FontScalingDialogDelegate>,
+    private val settingsPackageRepository: QSSettingsPackageRepository,
 ) :
     QSTileImpl<QSTile.State?>(
         host,
@@ -118,6 +120,7 @@
 
     override fun getLongClickIntent(): Intent? {
         return Intent(Settings.ACTION_TEXT_READING_SETTINGS)
+            .setPackage(settingsPackageRepository.getSettingsPackageName())
     }
 
     override fun getTileLabel(): CharSequence {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index fc82592..ec8d30b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -18,6 +18,7 @@
 
 import android.app.Dialog;
 import android.content.Intent;
+import android.media.projection.StopReason;
 import android.os.Handler;
 import android.os.Looper;
 import android.service.quicksettings.Tile;
@@ -226,7 +227,7 @@
     }
 
     private void stopRecording() {
-        mController.stopRecording();
+        mController.stopRecording(StopReason.STOP_QS_TILE);
     }
 
     private final class Callback implements RecordingController.RecordingStateChangeCallback {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
index 7516ca0..b21c3e4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
@@ -54,20 +54,21 @@
 
     private static final String TAG = "InternetAdapter";
 
-    private final InternetDialogController mInternetDialogController;
+    private final InternetDetailsContentController mInternetDetailsContentController;
     private final CoroutineScope mCoroutineScope;
     @Nullable
     private List<WifiEntry> mWifiEntries;
     @VisibleForTesting
     protected int mWifiEntriesCount;
     @VisibleForTesting
-    protected int mMaxEntriesCount = InternetDialogController.MAX_WIFI_ENTRY_COUNT;
+    protected int mMaxEntriesCount = InternetDetailsContentController.MAX_WIFI_ENTRY_COUNT;
 
     protected View mHolderView;
     protected Context mContext;
 
-    public InternetAdapter(InternetDialogController controller, CoroutineScope coroutineScope) {
-        mInternetDialogController = controller;
+    public InternetAdapter(InternetDetailsContentController controller,
+            CoroutineScope coroutineScope) {
+        mInternetDetailsContentController = controller;
         mCoroutineScope = coroutineScope;
     }
 
@@ -77,7 +78,8 @@
         mContext = viewGroup.getContext();
         mHolderView = LayoutInflater.from(mContext).inflate(R.layout.internet_list_item,
                 viewGroup, false);
-        return new InternetViewHolder(mHolderView, mInternetDialogController, mCoroutineScope);
+        return new InternetViewHolder(mHolderView, mInternetDetailsContentController,
+                mCoroutineScope);
     }
 
     @Override
@@ -137,16 +139,17 @@
         final TextView mWifiSummaryText;
         final ImageView mWifiEndIcon;
         final Context mContext;
-        final InternetDialogController mInternetDialogController;
+        final InternetDetailsContentController mInternetDetailsContentController;
         final CoroutineScope mCoroutineScope;
         @Nullable
         private Job mJob;
 
-        InternetViewHolder(View view, InternetDialogController internetDialogController,
+        InternetViewHolder(View view,
+                InternetDetailsContentController internetDetailsContentController,
                 CoroutineScope coroutineScope) {
             super(view);
             mContext = view.getContext();
-            mInternetDialogController = internetDialogController;
+            mInternetDetailsContentController = internetDetailsContentController;
             mCoroutineScope = coroutineScope;
             mContainerLayout = view.requireViewById(R.id.internet_container);
             mWifiListLayout = view.requireViewById(R.id.wifi_list);
@@ -169,7 +172,7 @@
             mWifiListLayout.setEnabled(shouldEnabled(wifiEntry));
             if (connectedState != WifiEntry.CONNECTED_STATE_DISCONNECTED) {
                 mWifiListLayout.setOnClickListener(
-                        v -> mInternetDialogController.launchWifiDetailsSetting(
+                        v -> mInternetDetailsContentController.launchWifiDetailsSetting(
                                 wifiEntry.getKey(), v));
                 return;
             }
@@ -193,7 +196,7 @@
                 if (mJob == null) {
                     mJob = WifiUtils.checkWepAllowed(mContext, mCoroutineScope, wifiEntry.getSsid(),
                             WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, intent -> {
-                                mInternetDialogController.startActivityForDialog(intent);
+                                mInternetDetailsContentController.startActivityForDialog(intent);
                                 return null;
                             }, () -> {
                                 wifiConnect(wifiEntry, view);
@@ -211,19 +214,20 @@
                         true /* connectForCaller */);
                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
-                mInternetDialogController.startActivityForDialog(intent);
+                mInternetDetailsContentController.startActivityForDialog(intent);
                 return;
             }
 
             if (wifiEntry.canConnect()) {
-                mInternetDialogController.connect(wifiEntry);
+                mInternetDetailsContentController.connect(wifiEntry);
                 return;
             }
 
             if (wifiEntry.isSaved()) {
                 Log.w(TAG, "The saved Wi-Fi network does not allow to connect. SSID:"
                         + wifiEntry.getSsid());
-                mInternetDialogController.launchWifiDetailsSetting(wifiEntry.getKey(), view);
+                mInternetDetailsContentController.launchWifiDetailsSetting(wifiEntry.getKey(),
+                        view);
             }
         }
 
@@ -239,7 +243,7 @@
 
         @Nullable
         Drawable getWifiDrawable(@NonNull WifiEntry wifiEntry) {
-            Drawable drawable = mInternetDialogController.getWifiDrawable(wifiEntry);
+            Drawable drawable = mInternetDetailsContentController.getWifiDrawable(wifiEntry);
             if (drawable == null) {
                 return null;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java
index 7036ef91..23210ef 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java
@@ -117,9 +117,9 @@
 /**
  * Controller for Internet Dialog.
  */
-public class InternetDialogController implements AccessPointController.AccessPointCallback {
+public class InternetDetailsContentController implements AccessPointController.AccessPointCallback {
 
-    private static final String TAG = "InternetDialogController";
+    private static final String TAG = "InternetDetailsContentController";
     private static final String ACTION_WIFI_SCANNING_SETTINGS =
             "android.settings.WIFI_SCANNING_SETTINGS";
     /**
@@ -244,7 +244,8 @@
     }
 
     @Inject
-    public InternetDialogController(@ShadeDisplayAware Context context, UiEventLogger uiEventLogger,
+    public InternetDetailsContentController(@ShadeDisplayAware Context context,
+            UiEventLogger uiEventLogger,
             ActivityStarter starter, AccessPointController accessPointController,
             SubscriptionManager subscriptionManager, TelephonyManager telephonyManager,
             @Nullable WifiManager wifiManager, ConnectivityManager connectivityManager,
@@ -260,7 +261,7 @@
             FeatureFlags featureFlags
     ) {
         if (DEBUG) {
-            Log.d(TAG, "Init InternetDialogController");
+            Log.d(TAG, "Init InternetDetailsContentController");
         }
         mHandler = handler;
         mWorkerHandler = workerHandler;
@@ -1108,13 +1109,13 @@
     static class WifiEntryConnectCallback implements WifiEntry.ConnectCallback {
         final ActivityStarter mActivityStarter;
         final WifiEntry mWifiEntry;
-        final InternetDialogController mInternetDialogController;
+        final InternetDetailsContentController mInternetDetailsContentController;
 
         WifiEntryConnectCallback(ActivityStarter activityStarter, WifiEntry connectWifiEntry,
-                InternetDialogController internetDialogController) {
+                InternetDetailsContentController internetDetailsContentController) {
             mActivityStarter = activityStarter;
             mWifiEntry = connectWifiEntry;
-            mInternetDialogController = internetDialogController;
+            mInternetDetailsContentController = internetDetailsContentController;
         }
 
         @Override
@@ -1129,7 +1130,8 @@
                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 mActivityStarter.startActivity(intent, false /* dismissShade */);
             } else if (status == CONNECT_STATUS_FAILURE_UNKNOWN) {
-                mInternetDialogController.makeOverlayToast(R.string.wifi_failed_connect_message);
+                mInternetDetailsContentController.makeOverlayToast(
+                        R.string.wifi_failed_connect_message);
             } else {
                 if (DEBUG) {
                     Log.d(TAG, "connect failure reason=" + status);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateLegacy.java
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateLegacy.java
index 5e9deec..82367eb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateLegacy.java
@@ -17,7 +17,7 @@
 
 import static com.android.settingslib.satellite.SatelliteDialogUtils.TYPE_IS_WIFI;
 import static com.android.systemui.Prefs.Key.QS_HAS_TURNED_OFF_MOBILE_DATA;
-import static com.android.systemui.qs.tiles.dialog.InternetDialogController.MAX_WIFI_ENTRY_COUNT;
+import static com.android.systemui.qs.tiles.dialog.InternetDetailsContentController.MAX_WIFI_ENTRY_COUNT;
 
 import android.app.AlertDialog;
 import android.content.Context;
@@ -90,9 +90,9 @@
 /**
  * Dialog for showing mobile network, connected Wi-Fi network and Wi-Fi networks.
  */
-public class InternetDialogDelegate implements
+public class InternetDialogDelegateLegacy implements
         SystemUIDialog.Delegate,
-        InternetDialogController.InternetDialogCallback {
+        InternetDetailsContentController.InternetDialogCallback {
     private static final String TAG = "InternetDialog";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
@@ -120,7 +120,7 @@
     @Nullable
     private AlertDialog mAlertDialog;
     private final UiEventLogger mUiEventLogger;
-    private final InternetDialogController mInternetDialogController;
+    private final InternetDetailsContentController mInternetDetailsContentController;
     private TextView mInternetDialogTitle;
     private TextView mInternetDialogSubTitle;
     private View mDivider;
@@ -184,7 +184,7 @@
 
     @AssistedFactory
     public interface Factory {
-        InternetDialogDelegate create(
+        InternetDialogDelegateLegacy create(
                 @Assisted(ABOVE_STATUS_BAR) boolean aboveStatusBar,
                 @Assisted(CAN_CONFIG_MOBILE_DATA) boolean canConfigMobileData,
                 @Assisted(CAN_CONFIG_WIFI) boolean canConfigWifi,
@@ -192,10 +192,10 @@
     }
 
     @AssistedInject
-    public InternetDialogDelegate(
+    public InternetDialogDelegateLegacy(
             @ShadeDisplayAware Context context,
             InternetDialogManager internetDialogManager,
-            InternetDialogController internetDialogController,
+            InternetDetailsContentController internetDetailsContentController,
             @Assisted(CAN_CONFIG_MOBILE_DATA) boolean canConfigMobileData,
             @Assisted(CAN_CONFIG_WIFI) boolean canConfigWifi,
             @Assisted(ABOVE_STATUS_BAR) boolean aboveStatusBar,
@@ -207,6 +207,8 @@
             KeyguardStateController keyguardStateController,
             SystemUIDialog.Factory systemUIDialogFactory,
             ShadeDialogContextInteractor shadeDialogContextInteractor) {
+        // TODO: b/377388104 QsDetailedView.assertInLegacyMode();
+
         mAboveStatusBar = aboveStatusBar;
         mSystemUIDialogFactory = systemUIDialogFactory;
         mShadeDialogContextInteractor = shadeDialogContextInteractor;
@@ -218,8 +220,8 @@
         mHandler = handler;
         mBackgroundExecutor = executor;
         mInternetDialogManager = internetDialogManager;
-        mInternetDialogController = internetDialogController;
-        mDefaultDataSubId = mInternetDialogController.getDefaultDataSubscriptionId();
+        mInternetDetailsContentController = internetDetailsContentController;
+        mDefaultDataSubId = mInternetDetailsContentController.getDefaultDataSubscriptionId();
         mCanConfigMobileData = canConfigMobileData;
         mCanConfigWifi = canConfigWifi;
         mCanChangeWifiState = WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(context);
@@ -227,7 +229,7 @@
         mCoroutineScope = coroutineScope;
         mUiEventLogger = uiEventLogger;
         mDialogTransitionAnimator = dialogTransitionAnimator;
-        mAdapter = new InternetAdapter(mInternetDialogController, coroutineScope);
+        mAdapter = new InternetAdapter(mInternetDetailsContentController, coroutineScope);
     }
 
     @Override
@@ -309,7 +311,8 @@
         setOnClickListener(dialog);
         mTurnWifiOnLayout.setBackground(null);
         mAirplaneModeButton.setVisibility(
-                mInternetDialogController.isAirplaneModeEnabled() ? View.VISIBLE : View.GONE);
+                mInternetDetailsContentController.isAirplaneModeEnabled() ? View.VISIBLE
+                        : View.GONE);
         mWifiRecyclerView.setLayoutManager(new LinearLayoutManager(context));
         mWifiRecyclerView.setAdapter(mAdapter);
 
@@ -324,7 +327,7 @@
 
         mLifecycleRegistry.setCurrentState(Lifecycle.State.RESUMED);
 
-        mInternetDialogController.onStart(this, mCanConfigWifi);
+        mInternetDetailsContentController.onStart(this, mCanConfigWifi);
         if (!mCanConfigWifi) {
             hideWifiViews();
         }
@@ -356,7 +359,7 @@
         mDoneButton.setOnClickListener(null);
         mShareWifiButton.setOnClickListener(null);
         mAirplaneModeButton.setOnClickListener(null);
-        mInternetDialogController.onStop();
+        mInternetDetailsContentController.onStop();
         mInternetDialogManager.destroyDialog();
     }
 
@@ -413,18 +416,20 @@
         internetContent.mInternetDialogSubTitle = getSubtitleText();
         if (shouldUpdateMobileNetwork) {
             internetContent.mActiveNetworkIsCellular =
-                    mInternetDialogController.activeNetworkIsCellular();
+                    mInternetDetailsContentController.activeNetworkIsCellular();
             internetContent.mIsCarrierNetworkActive =
-                    mInternetDialogController.isCarrierNetworkActive();
+                    mInternetDetailsContentController.isCarrierNetworkActive();
         }
-        internetContent.mIsAirplaneModeEnabled = mInternetDialogController.isAirplaneModeEnabled();
-        internetContent.mHasEthernet = mInternetDialogController.hasEthernet();
-        internetContent.mIsWifiEnabled = mInternetDialogController.isWifiEnabled();
-        internetContent.mHasActiveSubIdOnDds = mInternetDialogController.hasActiveSubIdOnDds();
-        internetContent.mIsDeviceLocked = mInternetDialogController.isDeviceLocked();
-        internetContent.mIsWifiScanEnabled = mInternetDialogController.isWifiScanEnabled();
+        internetContent.mIsAirplaneModeEnabled =
+                mInternetDetailsContentController.isAirplaneModeEnabled();
+        internetContent.mHasEthernet = mInternetDetailsContentController.hasEthernet();
+        internetContent.mIsWifiEnabled = mInternetDetailsContentController.isWifiEnabled();
+        internetContent.mHasActiveSubIdOnDds =
+                mInternetDetailsContentController.hasActiveSubIdOnDds();
+        internetContent.mIsDeviceLocked = mInternetDetailsContentController.isDeviceLocked();
+        internetContent.mIsWifiScanEnabled = mInternetDetailsContentController.isWifiScanEnabled();
         internetContent.mActiveAutoSwitchNonDdsSubId =
-                mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
+                mInternetDetailsContentController.getActiveAutoSwitchNonDdsSubId();
         return internetContent;
     }
 
@@ -432,8 +437,8 @@
         InternetContent internetContent = new InternetContent();
         internetContent.mInternetDialogTitleString = getDialogTitleText();
         internetContent.mInternetDialogSubTitle = getSubtitleText();
-        internetContent.mIsWifiEnabled = mInternetDialogController.isWifiEnabled();
-        internetContent.mIsDeviceLocked = mInternetDialogController.isDeviceLocked();
+        internetContent.mIsWifiEnabled = mInternetDetailsContentController.isWifiEnabled();
+        internetContent.mIsDeviceLocked = mInternetDetailsContentController.isDeviceLocked();
         return internetContent;
     }
 
@@ -447,15 +452,15 @@
             if (autoSwitchNonDdsSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
                 showTurnOffAutoDataSwitchDialog(dialog, autoSwitchNonDdsSubId);
             }
-            mInternetDialogController.connectCarrierNetwork();
+            mInternetDetailsContentController.connectCarrierNetwork();
         });
         mMobileDataToggle.setOnClickListener(v -> {
             boolean isChecked = mMobileDataToggle.isChecked();
             if (!isChecked && shouldShowMobileDialog()) {
                 mMobileDataToggle.setChecked(true);
                 showTurnOffMobileDialog(dialog);
-            } else if (mInternetDialogController.isMobileDataEnabled() != isChecked) {
-                mInternetDialogController.setMobileDataEnabled(
+            } else if (mInternetDetailsContentController.isMobileDataEnabled() != isChecked) {
+                mInternetDetailsContentController.setMobileDataEnabled(
                         dialog.getContext(), mDefaultDataSubId, isChecked, false);
             }
         });
@@ -466,12 +471,13 @@
         });
         mDoneButton.setOnClickListener(v -> dialog.dismiss());
         mShareWifiButton.setOnClickListener(v -> {
-            if (mInternetDialogController.mayLaunchShareWifiSettings(mConnectedWifiEntry, v)) {
+            if (mInternetDetailsContentController.mayLaunchShareWifiSettings(mConnectedWifiEntry,
+                    v)) {
                 mUiEventLogger.log(InternetDialogEvent.SHARE_WIFI_QS_BUTTON_CLICKED);
             }
         });
         mAirplaneModeButton.setOnClickListener(v -> {
-            mInternetDialogController.setAirplaneModeDisabled();
+            mInternetDetailsContentController.setAirplaneModeDisabled();
         });
     }
 
@@ -495,10 +501,10 @@
     }
 
     private void setWifiEnable(boolean isChecked) {
-        if (mInternetDialogController.isWifiEnabled() == isChecked) {
+        if (mInternetDetailsContentController.isWifiEnabled() == isChecked) {
             return;
         }
-        mInternetDialogController.setWifiEnabled(isChecked);
+        mInternetDetailsContentController.setWifiEnabled(isChecked);
     }
 
     @MainThread
@@ -534,7 +540,7 @@
             }
         } else {
             mMobileNetworkLayout.setVisibility(View.VISIBLE);
-            mMobileDataToggle.setChecked(mInternetDialogController.isMobileDataEnabled());
+            mMobileDataToggle.setChecked(mInternetDetailsContentController.isMobileDataEnabled());
             mMobileTitleText.setText(getMobileNetworkTitle(mDefaultDataSubId));
             String summary = getMobileNetworkSummary(mDefaultDataSubId);
             if (!TextUtils.isEmpty(summary)) {
@@ -679,10 +685,10 @@
         mConnectedWifiTitleText.setText(mConnectedWifiEntry.getTitle());
         mConnectedWifiSummaryText.setText(mConnectedWifiEntry.getSummary(false));
         mConnectedWifiIcon.setImageDrawable(
-                mInternetDialogController.getInternetWifiDrawable(mConnectedWifiEntry));
+                mInternetDetailsContentController.getInternetWifiDrawable(mConnectedWifiEntry));
         mWifiSettingsIcon.setColorFilter(
                 mDialog.getContext().getColor(R.color.connected_network_primary_color));
-        if (mInternetDialogController.getConfiguratorQrCodeGeneratorIntentOrNull(
+        if (mInternetDetailsContentController.getConfiguratorQrCodeGeneratorIntentOrNull(
                 mConnectedWifiEntry) != null) {
             mShareWifiButton.setVisibility(View.VISIBLE);
         } else {
@@ -748,7 +754,7 @@
         if (TextUtils.isEmpty(mWifiScanNotifyText.getText())) {
             final AnnotationLinkSpan.LinkInfo linkInfo = new AnnotationLinkSpan.LinkInfo(
                     AnnotationLinkSpan.LinkInfo.DEFAULT_ANNOTATION,
-                    mInternetDialogController::launchWifiScanningSetting);
+                    mInternetDetailsContentController::launchWifiScanningSetting);
             mWifiScanNotifyText.setText(AnnotationLinkSpan.linkify(
                     mDialog.getContext().getText(R.string.wifi_scan_notify_message), linkInfo));
             mWifiScanNotifyText.setMovementMethod(LinkMovementMethod.getInstance());
@@ -760,37 +766,38 @@
         if (mConnectedWifiEntry == null) {
             return;
         }
-        mInternetDialogController.launchWifiDetailsSetting(mConnectedWifiEntry.getKey(), view);
+        mInternetDetailsContentController.launchWifiDetailsSetting(mConnectedWifiEntry.getKey(),
+                view);
     }
 
     /** For DSDS auto data switch **/
     void onClickConnectedSecondarySub(View view) {
-        mInternetDialogController.launchMobileNetworkSettings(view);
+        mInternetDetailsContentController.launchMobileNetworkSettings(view);
     }
 
     void onClickSeeMoreButton(View view) {
-        mInternetDialogController.launchNetworkSetting(view);
+        mInternetDetailsContentController.launchNetworkSetting(view);
     }
 
     CharSequence getDialogTitleText() {
-        return mInternetDialogController.getDialogTitleText();
+        return mInternetDetailsContentController.getDialogTitleText();
     }
 
     @Nullable
     CharSequence getSubtitleText() {
-        return mInternetDialogController.getSubtitleText(mIsProgressBarVisible);
+        return mInternetDetailsContentController.getSubtitleText(mIsProgressBarVisible);
     }
 
     private Drawable getSignalStrengthDrawable(int subId) {
-        return mInternetDialogController.getSignalStrengthDrawable(subId);
+        return mInternetDetailsContentController.getSignalStrengthDrawable(subId);
     }
 
     CharSequence getMobileNetworkTitle(int subId) {
-        return mInternetDialogController.getMobileNetworkTitle(subId);
+        return mInternetDetailsContentController.getMobileNetworkTitle(subId);
     }
 
     String getMobileNetworkSummary(int subId) {
-        return mInternetDialogController.getMobileNetworkSummary(subId);
+        return mInternetDetailsContentController.getMobileNetworkSummary(subId);
     }
 
     private void setProgressBarVisible(boolean visible) {
@@ -810,7 +817,7 @@
         }
         boolean flag = Prefs.getBoolean(mDialog.getContext(), QS_HAS_TURNED_OFF_MOBILE_DATA,
                 false);
-        if (mInternetDialogController.isMobileDataEnabled() && !flag) {
+        if (mInternetDetailsContentController.isMobileDataEnabled() && !flag) {
             return true;
         }
         return false;
@@ -819,7 +826,8 @@
     private void showTurnOffMobileDialog(SystemUIDialog dialog) {
         Context context = dialog.getContext();
         CharSequence carrierName = getMobileNetworkTitle(mDefaultDataSubId);
-        boolean isInService = mInternetDialogController.isVoiceStateInService(mDefaultDataSubId);
+        boolean isInService = mInternetDetailsContentController.isVoiceStateInService(
+                mDefaultDataSubId);
         if (TextUtils.isEmpty(carrierName) || !isInService) {
             carrierName = context.getString(R.string.mobile_data_disable_message_default_carrier);
         }
@@ -831,7 +839,7 @@
                 .setPositiveButton(
                         com.android.internal.R.string.alert_windows_notification_turn_off_action,
                         (d, w) -> {
-                            mInternetDialogController.setMobileDataEnabled(context,
+                            mInternetDetailsContentController.setMobileDataEnabled(context,
                                     mDefaultDataSubId, false, false);
                             mMobileDataToggle.setChecked(false);
                             Prefs.putBoolean(context, QS_HAS_TURNED_OFF_MOBILE_DATA, true);
@@ -858,7 +866,7 @@
                         })
                 .setPositiveButton(R.string.auto_data_switch_dialog_positive_button,
                         (d, w) -> {
-                            mInternetDialogController
+                            mInternetDetailsContentController
                                     .setAutoDataSwitchMobileDataPolicy(subId, false);
                             if (mSecondaryMobileNetworkLayout != null) {
                                 mSecondaryMobileNetworkLayout.setVisibility(View.GONE);
@@ -938,7 +946,7 @@
             @Nullable WifiEntry connectedEntry, boolean hasMoreWifiEntries) {
         // Should update the carrier network layout when it is connected under airplane mode ON.
         boolean shouldUpdateCarrierNetwork = mMobileNetworkLayout.getVisibility() == View.VISIBLE
-                && mInternetDialogController.isAirplaneModeEnabled();
+                && mInternetDetailsContentController.isAirplaneModeEnabled();
         mHandler.post(() -> {
             mConnectedWifiEntry = connectedEntry;
             mWifiEntriesCount = wifiEntries == null ? 0 : wifiEntries.size();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogManager.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogManager.kt
index f674971..8a54648 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogManager.kt
@@ -32,13 +32,13 @@
 private const val TAG = "InternetDialogFactory"
 private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
 
-/** Factory to create [InternetDialogDelegate] objects. */
+/** Factory to create [InternetDialogDelegateLegacy] objects. */
 @SysUISingleton
 class InternetDialogManager
 @Inject
 constructor(
     private val dialogTransitionAnimator: DialogTransitionAnimator,
-    private val dialogFactory: InternetDialogDelegate.Factory,
+    private val dialogFactory: InternetDialogDelegateLegacy.Factory,
     @Background private val bgDispatcher: CoroutineDispatcher,
 ) {
     private lateinit var coroutineScope: CoroutineScope
@@ -48,8 +48,8 @@
     }
 
     /**
-     * Creates a [InternetDialogDelegate]. The dialog will be animated from [expandable] if it is
-     * not null.
+     * Creates a [InternetDialogDelegateLegacy]. The dialog will be animated from [expandable] if
+     * it is not null.
      */
     fun create(
         aboveStatusBar: Boolean,
@@ -64,6 +64,7 @@
             return
         } else {
             coroutineScope = CoroutineScope(bgDispatcher + newTracingContext("InternetDialogScope"))
+            // TODO: b/377388104 check the QsDetailedView flag to use the correct dialogFactory
             dialog =
                 dialogFactory
                     .create(aboveStatusBar, canConfigMobileData, canConfigWifi, coroutineScope)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt
index dfdec3b..b774643 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt
@@ -19,6 +19,7 @@
 import android.content.Intent
 import android.provider.Settings
 import com.android.systemui.accessibility.data.repository.ColorCorrectionRepository
+import com.android.systemui.qs.shared.QSSettingsPackageRepository
 import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
 import com.android.systemui.qs.tiles.base.interactor.QSTileInput
 import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
@@ -32,21 +33,20 @@
 constructor(
     private val colorCorrectionRepository: ColorCorrectionRepository,
     private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler,
+    private val settingsPackageRepository: QSSettingsPackageRepository,
 ) : QSTileUserActionInteractor<ColorCorrectionTileModel> {
 
     override suspend fun handleInput(input: QSTileInput<ColorCorrectionTileModel>): Unit =
         with(input) {
             when (action) {
                 is QSTileUserAction.Click -> {
-                    colorCorrectionRepository.setIsEnabled(
-                        !data.isEnabled,
-                        user,
-                    )
+                    colorCorrectionRepository.setIsEnabled(!data.isEnabled, user)
                 }
                 is QSTileUserAction.LongClick -> {
                     qsTileIntentUserActionHandler.handle(
                         action.expandable,
                         Intent(Settings.ACTION_COLOR_CORRECTION_SETTINGS)
+                            .setPackage(settingsPackageRepository.getSettingsPackageName()),
                     )
                 }
                 is QSTileUserAction.ToggleClick -> {}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt
index 6ab5796..0ebb51e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.qs.shared.QSSettingsPackageRepository
 import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
 import com.android.systemui.qs.tiles.base.interactor.QSTileInput
 import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
@@ -46,6 +47,7 @@
     private val keyguardStateController: KeyguardStateController,
     private val dialogTransitionAnimator: DialogTransitionAnimator,
     private val activityStarter: ActivityStarter,
+    private val settingsPackageRepository: QSSettingsPackageRepository,
 ) : QSTileUserActionInteractor<FontScalingTileModel> {
 
     override suspend fun handleInput(input: QSTileInput<FontScalingTileModel>): Unit =
@@ -63,7 +65,7 @@
                                 ?.dialogTransitionController(
                                     DialogCuj(
                                         InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
-                                        INTERACTION_JANK_TAG
+                                        INTERACTION_JANK_TAG,
                                     )
                                 )
                                 ?.let { dialogTransitionAnimator.show(dialog, it) } ?: dialog.show()
@@ -78,7 +80,7 @@
                             /* cancelAction= */ null,
                             /* dismissShade= */ true,
                             /* afterKeyguardGone= */ true,
-                            /* deferred= */ false
+                            /* deferred= */ false,
                         )
                     }
                 }
@@ -86,6 +88,7 @@
                     qsTileIntentUserActionHandler.handle(
                         action.expandable,
                         Intent(Settings.ACTION_TEXT_READING_SETTINGS)
+                            .setPackage(settingsPackageRepository.getSettingsPackageName()),
                     )
                 }
                 is QSTileUserAction.ToggleClick -> {}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt
index aa83877..f783497 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt
@@ -19,6 +19,7 @@
 import android.content.Intent
 import android.provider.Settings
 import com.android.systemui.accessibility.data.repository.ColorInversionRepository
+import com.android.systemui.qs.shared.QSSettingsPackageRepository
 import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
 import com.android.systemui.qs.tiles.base.interactor.QSTileInput
 import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
@@ -32,21 +33,20 @@
 constructor(
     private val colorInversionRepository: ColorInversionRepository,
     private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler,
+    private val settingsPackageRepository: QSSettingsPackageRepository,
 ) : QSTileUserActionInteractor<ColorInversionTileModel> {
 
     override suspend fun handleInput(input: QSTileInput<ColorInversionTileModel>): Unit =
         with(input) {
             when (action) {
                 is QSTileUserAction.Click -> {
-                    colorInversionRepository.setIsEnabled(
-                        !data.isEnabled,
-                        user,
-                    )
+                    colorInversionRepository.setIsEnabled(!data.isEnabled, user)
                 }
                 is QSTileUserAction.LongClick -> {
                     qsTileIntentUserActionHandler.handle(
                         action.expandable,
                         Intent(Settings.ACTION_COLOR_INVERSION_SETTINGS)
+                            .setPackage(settingsPackageRepository.getSettingsPackageName()),
                     )
                 }
                 is QSTileUserAction.ToggleClick -> {}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt
index 85aa674..9453447 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.qs.tiles.impl.screenrecord.domain.interactor
 
+import android.media.projection.StopReason
 import android.util.Log
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.systemui.animation.DialogCuj
@@ -61,7 +62,9 @@
                             Log.d(TAG, "Cancelling countdown")
                             withContext(backgroundContext) { recordingController.cancelCountdown() }
                         }
-                        is ScreenRecordModel.Recording -> screenRecordRepository.stopRecording()
+                        is ScreenRecordModel.Recording -> {
+                            screenRecordRepository.stopRecording(StopReason.STOP_QS_TILE)
+                        }
                         is ScreenRecordModel.DoingNothing ->
                             withContext(mainContext) {
                                 showPrompt(action.expandable, user.identifier)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModel.kt
index 8ef51af..c0c0aea 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeOverlayContentViewModel.kt
@@ -16,8 +16,10 @@
 
 package com.android.systemui.qs.ui.viewmodel
 
+import androidx.compose.runtime.getValue
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.lifecycle.Hydrator
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -28,6 +30,8 @@
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
 
 /**
  * Models UI state used to render the content of the quick settings shade overlay.
@@ -44,10 +48,21 @@
     quickSettingsContainerViewModelFactory: QuickSettingsContainerViewModel.Factory,
 ) : ExclusiveActivatable() {
 
+    private val hydrator = Hydrator("QuickSettingsContainerViewModel.hydrator")
+
+    val showHeader: Boolean by
+        hydrator.hydratedStateOf(
+            traceName = "showHeader",
+            initialValue = !shadeInteractor.isShadeLayoutWide.value,
+            source = shadeInteractor.isShadeLayoutWide.map { !it },
+        )
+
     val quickSettingsContainerViewModel = quickSettingsContainerViewModelFactory.create(false)
 
     override suspend fun onActivated(): Nothing {
         coroutineScope {
+            launch { hydrator.activate() }
+
             launch {
                 sceneInteractor.currentScene.collect { currentScene ->
                     when (currentScene) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
index d7463f8..9ee99e4 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.media.projection.StopReason;
 import android.os.Bundle;
 import android.os.CountDownTimer;
 import android.os.Process;
@@ -58,6 +59,7 @@
     private boolean mIsStarting;
     private boolean mIsRecording;
     private PendingIntent mStopIntent;
+    private @StopReason int mStopReason = StopReason.STOP_UNKNOWN;
     private final Bundle mInteractiveBroadcastOption;
     private CountDownTimer mCountDownTimer = null;
     private final Executor mMainExecutor;
@@ -83,7 +85,7 @@
             new UserTracker.Callback() {
                 @Override
                 public void onUserChanged(int newUser, @NonNull Context userContext) {
-                    stopRecording();
+                    stopRecording(StopReason.STOP_USER_SWITCH);
                 }
             };
 
@@ -240,9 +242,11 @@
     }
 
     /**
-     * Stop the recording
+     * Stop the recording and sets the stop reason to be used by the RecordingService
+     * @param stopReason the method of the recording stopped (i.e. QS tile, status bar chip, etc.)
      */
-    public void stopRecording() {
+    public void stopRecording(@StopReason int stopReason) {
+        mStopReason = stopReason;
         try {
             if (mStopIntent != null) {
                 mRecordingControllerLogger.logRecordingStopped();
@@ -277,6 +281,10 @@
         }
     }
 
+    public @StopReason int getStopReason() {
+        return mStopReason;
+    }
+
     @Override
     public void addCallback(@NonNull RecordingStateChangeCallback listener) {
         mListeners.add(listener);
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index 8c207d1..f7b5271 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -26,6 +26,7 @@
 import android.content.Intent;
 import android.graphics.drawable.Icon;
 import android.media.MediaRecorder;
+import android.media.projection.StopReason;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -78,6 +79,7 @@
     private static final String EXTRA_SHOW_TAPS = "extra_showTaps";
     private static final String EXTRA_CAPTURE_TARGET = "extra_captureTarget";
     private static final String EXTRA_DISPLAY_ID = "extra_displayId";
+    private static final String EXTRA_STOP_REASON = "extra_stopReason";
 
     protected static final String ACTION_START = "com.android.systemui.screenrecord.START";
     protected static final String ACTION_SHOW_START_NOTIF =
@@ -242,7 +244,8 @@
                 // Check user ID - we may be getting a stop intent after user switch, in which case
                 // we want to post the notifications for that user, which is NOT current user
                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_ID_NOT_SPECIFIED);
-                stopService(userId);
+                int stopReason = intent.getIntExtra(EXTRA_STOP_REASON, mController.getStopReason());
+                stopService(userId, stopReason);
                 break;
 
             case ACTION_SHARE:
@@ -486,11 +489,11 @@
                 getTag(), notificationIdForGroup, groupNotif, currentUser);
     }
 
-    private void stopService() {
-        stopService(USER_ID_NOT_SPECIFIED);
+    private void stopService(@StopReason int stopReason) {
+        stopService(USER_ID_NOT_SPECIFIED, stopReason);
     }
 
-    private void stopService(int userId) {
+    private void stopService(int userId, @StopReason int stopReason) {
         if (userId == USER_ID_NOT_SPECIFIED) {
             userId = mUserContextTracker.getUserContext().getUserId();
         }
@@ -499,7 +502,7 @@
         setTapsVisible(mOriginalShowTaps);
         try {
             if (getRecorder() != null) {
-                getRecorder().end();
+                getRecorder().end(stopReason);
             }
             saveRecording(userId);
         } catch (RuntimeException exception) {
@@ -598,7 +601,8 @@
      * @return
      */
     protected Intent getNotificationIntent(Context context) {
-        return new Intent(context, this.getClass()).setAction(ACTION_STOP_NOTIF);
+        return new Intent(context, this.getClass()).setAction(ACTION_STOP_NOTIF)
+                .putExtra(EXTRA_STOP_REASON, StopReason.STOP_HOST_APP);
     }
 
     private Intent getShareIntent(Context context, Uri path) {
@@ -610,14 +614,17 @@
     @Override
     public void onInfo(MediaRecorder mr, int what, int extra) {
         Log.d(getTag(), "Media recorder info: " + what);
-        onStartCommand(getStopIntent(this), 0, 0);
+        // Stop due to record reaching size limits so log as stopping due to error
+        Intent stopIntent = getStopIntent(this);
+        stopIntent.putExtra(EXTRA_STOP_REASON, StopReason.STOP_ERROR);
+        onStartCommand(stopIntent, 0, 0);
     }
 
     @Override
-    public void onStopped() {
+    public void onStopped(@StopReason int stopReason) {
         if (mController.isRecording()) {
             Log.d(getTag(), "Stopping recording because the system requested the stop");
-            stopService();
+            stopService(stopReason);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
index 2ca0621..f4455bf 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
@@ -41,6 +41,7 @@
 import android.media.projection.IMediaProjectionManager;
 import android.media.projection.MediaProjection;
 import android.media.projection.MediaProjectionManager;
+import android.media.projection.StopReason;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.IBinder;
@@ -300,7 +301,7 @@
     /**
      * End screen recording, throws an exception if stopping recording failed
      */
-    void end() throws IOException {
+    void end(@StopReason int stopReason) throws IOException {
         Closer closer = new Closer();
 
         // MediaRecorder might throw RuntimeException if stopped immediately after starting
@@ -309,7 +310,17 @@
         closer.register(mMediaRecorder::release);
         closer.register(mInputSurface::release);
         closer.register(mVirtualDisplay::release);
-        closer.register(mMediaProjection::stop);
+        closer.register(() -> {
+            if (stopReason == StopReason.STOP_UNKNOWN) {
+                // Attempt to call MediaProjection#stop() even if it might have already been called.
+                // If projection has already been stopped, then nothing will happen. Else, stop
+                // will be logged as a manually requested stop from host app.
+                mMediaProjection.stop();
+            } else {
+                // In any other case, the stop reason is related to the recorder, so pass it on here
+                mMediaProjection.stop(stopReason);
+            }
+        });
         closer.register(this::stopInternalAudioRecording);
 
         closer.close();
@@ -323,7 +334,7 @@
     @Override
     public void onStop() {
         Log.d(TAG, "The system notified about stopping the projection");
-        mListener.onStopped();
+        mListener.onStopped(StopReason.STOP_UNKNOWN);
     }
 
     private void stopInternalAudioRecording() {
@@ -453,7 +464,7 @@
          * For example, this might happen when doing partial screen sharing of an app
          * and the app that is being captured is closed.
          */
-        void onStopped();
+        void onStopped(@StopReason int stopReason);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepository.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepository.kt
index 9eeb3b9..b6b8ffa 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepository.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.screenrecord.data.repository
 
+import android.media.projection.StopReason
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.screenrecord.RecordingController
@@ -41,7 +42,7 @@
     val screenRecordState: Flow<ScreenRecordModel>
 
     /** Stops the recording. */
-    suspend fun stopRecording()
+    suspend fun stopRecording(@StopReason stopReason: Int)
 }
 
 @SysUISingleton
@@ -95,7 +96,7 @@
         }
     }
 
-    override suspend fun stopRecording() {
-        withContext(bgCoroutineContext) { recordingController.stopRecording() }
+    override suspend fun stopRecording(@StopReason stopReason: Int) {
+        withContext(bgCoroutineContext) { recordingController.stopRecording(stopReason) }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
index 10ac2cf..0650f86 100644
--- a/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.scrim;
 
-import static com.android.systemui.Flags.notificationShadeBlur;
-
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
@@ -216,7 +214,7 @@
     public void draw(@NonNull Canvas canvas) {
         mPaint.setColor(mMainColor);
         mPaint.setAlpha(mAlpha);
-        if (notificationShadeBlur() || WindowBlurFlag.isEnabled()) {
+        if (WindowBlurFlag.isEnabled()) {
             // TODO (b/381263600), wire this at ScrimController, move it to PrimaryBouncerTransition
             mPaint.setAlpha((int) (0.5f * mAlpha));
         }
diff --git a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
index 0f80e74..03a8d17 100644
--- a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.scrim;
 
-import static com.android.systemui.Flags.notificationShadeBlur;
-
 import static java.lang.Float.isNaN;
 
 import android.annotation.NonNull;
@@ -44,6 +42,7 @@
 import com.android.systemui.res.R;
 import com.android.systemui.shade.TouchLogger;
 import com.android.systemui.util.LargeScreenUtils;
+import com.android.systemui.window.flag.WindowBlurFlag;
 
 import java.util.concurrent.Executor;
 
@@ -253,7 +252,7 @@
             if (mBlendWithMainColor) {
                 mainTinted = ColorUtils.blendARGB(mColors.getMainColor(), mTintColor, tintAmount);
             }
-            if (notificationShadeBlur()) {
+            if (WindowBlurFlag.isEnabled()) {
                 int layerAbove = ColorUtils.setAlphaComponent(
                         getResources().getColor(R.color.shade_panel, null),
                         (int) (0.4f * 255));
diff --git a/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt
index 60ed2de..b0cbc06 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/DisplayTrackerImpl.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.settings
 
 import android.hardware.display.DisplayManager
-import android.hardware.display.DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS
+import android.hardware.display.DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS
 import android.os.Handler
 import android.view.Display
 import androidx.annotation.GuardedBy
@@ -104,7 +104,7 @@
                     displayBrightnessChangedListener,
                     backgroundHandler,
                     /* eventFlags */ 0,
-                    PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS,
+                    PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS,
                 )
             }
             brightnessCallbacks.add(DisplayTrackerDataItem(WeakReference(callback), executor))
diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
index 61ac1a02..a379ef7 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
@@ -67,6 +67,7 @@
 import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf
+import com.android.systemui.util.kotlin.Quad
 import com.android.systemui.util.kotlin.collectFlow
 import java.util.function.Consumer
 import javax.inject.Inject
@@ -409,11 +410,12 @@
                 shadeInteractor.isAnyFullyExpanded,
                 shadeInteractor.isUserInteracting,
                 shadeInteractor.isShadeFullyCollapsed,
-                ::Triple,
+                shadeInteractor.isQsExpanded,
+                ::Quad,
             ),
-            { (isFullyExpanded, isUserInteracting, isShadeFullyCollapsed) ->
+            { (isFullyExpanded, isUserInteracting, isShadeFullyCollapsed, isQsExpanded) ->
                 shadeConsumingTouches = isUserInteracting
-                shadeShowing = !isShadeFullyCollapsed
+                shadeShowing = isQsExpanded || !isShadeFullyCollapsed
                 val expandedAndNotInteractive = isFullyExpanded && !isUserInteracting
 
                 // If we ever are fully expanded and not interacting, capture this state as we
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 197e6fc..e168025 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -118,7 +118,6 @@
 import com.android.systemui.keyguard.shared.model.TransitionState;
 import com.android.systemui.keyguard.shared.model.TransitionStep;
 import com.android.systemui.keyguard.ui.binder.KeyguardLongPressViewBinder;
-import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition;
 import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel;
 import com.android.systemui.media.controls.domain.pipeline.MediaDataManager;
@@ -952,7 +951,7 @@
         if (isBouncerShowing && isExpanded()) {
             // Blur the shade much lesser than the background surface so that the surface is
             // distinguishable from the background.
-            float shadeBlurEffect = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS / 3;
+            float shadeBlurEffect = mDepthController.getMaxBlurRadiusPx() / 3;
             mView.setRenderEffect(RenderEffect.createBlurEffect(
                     shadeBlurEffect,
                     shadeBlurEffect,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 839d459..e5dcd23 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -23,6 +23,7 @@
 
 import android.app.StatusBarManager;
 import android.util.Log;
+import android.view.Choreographer;
 import android.view.GestureDetector;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -60,6 +61,7 @@
 import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
 import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround;
 import com.android.systemui.shared.animation.DisableSubpixelTextTransitionListener;
+import com.android.systemui.statusbar.BlurUtils;
 import com.android.systemui.statusbar.DragDownHelper;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.NotificationInsetsController;
@@ -79,6 +81,8 @@
 import com.android.systemui.unfold.SysUIUnfoldComponent;
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
 import com.android.systemui.util.time.SystemClock;
+import com.android.systemui.window.ui.WindowRootViewBinder;
+import com.android.systemui.window.ui.viewmodel.WindowRootViewModel;
 
 import kotlinx.coroutines.ExperimentalCoroutinesApi;
 
@@ -160,6 +164,9 @@
     @ExperimentalCoroutinesApi
     @Inject
     public NotificationShadeWindowViewController(
+            BlurUtils blurUtils,
+            WindowRootViewModel.Factory windowRootViewModelFactory,
+            Choreographer choreographer,
             LockscreenShadeTransitionController transitionController,
             FalsingCollector falsingCollector,
             SysuiStatusBarStateController statusBarStateController,
@@ -259,9 +266,18 @@
         if (ShadeWindowGoesAround.isEnabled()) {
             mView.setConfigurationForwarder(configurationForwarder.get());
         }
+        bindWindowRootView(blurUtils, windowRootViewModelFactory, choreographer);
         dumpManager.registerDumpable(this);
     }
 
+    private void bindWindowRootView(BlurUtils blurUtils,
+            WindowRootViewModel.Factory windowRootViewModelFactory, Choreographer choreographer) {
+        if (SceneContainerFlag.isEnabled()) return;
+
+        WindowRootViewBinder.INSTANCE.bind(mView, windowRootViewModelFactory, blurUtils,
+                choreographer);
+    }
+
     private void bindBouncer(BouncerViewBinder bouncerViewBinder) {
         mBouncerParentView = mView.findViewById(R.id.keyguard_bouncer_container);
         bouncerViewBinder.bind(mBouncerParentView);
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt
index 201dc03..4edba27 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDialogContextInteractor.kt
@@ -77,7 +77,17 @@
     private fun getContextOrDefault(displayId: Int): Context {
         return try {
             traceSection({ "Getting dialog context for displayId=$displayId" }) {
-                displayWindowPropertyRepository.get().get(displayId, DIALOG_WINDOW_TYPE).context
+                val displayWindowProperties =
+                    displayWindowPropertyRepository.get().get(displayId, DIALOG_WINDOW_TYPE)
+                if (displayWindowProperties == null) {
+                    Log.e(
+                        TAG,
+                        "DisplayWindowPropertiesRepository returned null for display $displayId. Returning default one",
+                    )
+                    defaultContext
+                } else {
+                    displayWindowProperties.context
+                }
             }
         } catch (e: Exception) {
             // This can happen if the display was disconnected in the meantime.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
index d343ed5a..04bdfbe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar
 
 import android.app.ActivityManager
-import android.content.res.Resources
 import android.os.SystemProperties
 import android.os.Trace
 import android.os.Trace.TRACE_TAG_APP
@@ -29,28 +28,20 @@
 import android.view.ViewRootImpl
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.Dumpable
-import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
 import java.io.PrintWriter
 import javax.inject.Inject
-import com.android.systemui.Flags.notificationShadeBlur
+import com.android.systemui.keyguard.ui.transitions.BlurConfig
 
 @SysUISingleton
 open class BlurUtils @Inject constructor(
-    @Main private val resources: Resources,
+    blurConfig: BlurConfig,
     private val crossWindowBlurListeners: CrossWindowBlurListeners,
     dumpManager: DumpManager
 ) : Dumpable {
-    val minBlurRadius = resources.getDimensionPixelSize(R.dimen.min_window_blur_radius)
-    val maxBlurRadius =
-        if (notificationShadeBlur()) {
-            resources.getDimensionPixelSize(R.dimen.max_shade_window_blur_radius)
-        } else {
-            resources.getDimensionPixelSize(R.dimen.max_window_blur_radius)
-        }
-
+    val minBlurRadius = blurConfig.minBlurRadiusPx
+    val maxBlurRadius = blurConfig.maxBlurRadiusPx
 
     private var lastAppliedBlur = 0
     private var earlyWakeupEnabled = false
@@ -66,7 +57,7 @@
         if (ratio == 0f) {
             return 0f
         }
-        return MathUtils.lerp(minBlurRadius.toFloat(), maxBlurRadius.toFloat(), ratio)
+        return MathUtils.lerp(minBlurRadius, maxBlurRadius, ratio)
     }
 
     /**
@@ -76,7 +67,7 @@
         if (blur == 0f) {
             return 0f
         }
-        return MathUtils.map(minBlurRadius.toFloat(), maxBlurRadius.toFloat(),
+        return MathUtils.map(minBlurRadius, maxBlurRadius,
                 0f /* maxStart */, 1f /* maxStop */, blur)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 3408f4f..e83cded 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -34,9 +34,9 @@
 import androidx.dynamicanimation.animation.SpringForce
 import com.android.app.animation.Interpolators
 import com.android.systemui.Dumpable
-import com.android.systemui.Flags.notificationShadeBlur
 import com.android.systemui.animation.ShadeInterpolation
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.shade.ShadeExpansionChangeEvent
@@ -50,10 +50,14 @@
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.statusbar.policy.SplitShadeStateController
 import com.android.systemui.util.WallpaperController
+import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor
+import com.android.systemui.window.flag.WindowBlurFlag
 import java.io.PrintWriter
 import javax.inject.Inject
 import kotlin.math.max
 import kotlin.math.sign
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 
 /**
  * Responsible for blurring the notification shade window, and applying a zoom effect to the
@@ -73,6 +77,8 @@
     private val dozeParameters: DozeParameters,
     private val context: Context,
     private val splitShadeStateController: SplitShadeStateController,
+    private val windowRootViewBlurInteractor: WindowRootViewBlurInteractor,
+    @Application private val applicationScope: CoroutineScope,
     dumpManager: DumpManager,
     configurationController: ConfigurationController,
 ) : ShadeExpansionListener, Dumpable {
@@ -105,6 +111,8 @@
     // Only for dumpsys
     private var lastAppliedBlur = 0
 
+    val maxBlurRadiusPx = blurUtils.maxBlurRadius
+
     // Shade expansion offset that happens when pulling down on a HUN.
     var panelPullDownMinFraction = 0f
 
@@ -162,6 +170,8 @@
             shadeAnimation.finishIfRunning()
         }
 
+    private var zoomOutCalculatedFromShadeRadius: Float = 0.0f
+
     /** We're unlocking, and should not blur as the panel expansion changes. */
     var blursDisabledForUnlock: Boolean = false
         set(value) {
@@ -190,8 +200,8 @@
         val animationRadius =
             MathUtils.constrain(
                 shadeAnimation.radius,
-                blurUtils.minBlurRadius.toFloat(),
-                blurUtils.maxBlurRadius.toFloat(),
+                blurUtils.minBlurRadius,
+                blurUtils.maxBlurRadius,
             )
         val expansionRadius =
             blurUtils.blurRadiusOfRatio(
@@ -216,7 +226,7 @@
         val zoomOut = blurRadiusToZoomOut(blurRadius = shadeRadius)
         // Make blur be 0 if it is necessary to stop blur effect.
         if (scrimsVisible) {
-            if (!notificationShadeBlur()) {
+            if (!WindowBlurFlag.isEnabled) {
                 blur = 0
             }
         }
@@ -244,7 +254,7 @@
     }
 
     private val shouldBlurBeOpaque: Boolean
-        get() = if (notificationShadeBlur()) false else scrimsVisible && !blursDisabledForAppLaunch
+        get() = if (WindowBlurFlag.isEnabled) false else scrimsVisible && !blursDisabledForAppLaunch
 
     /** Callback that updates the window blur value and is called only once per frame. */
     @VisibleForTesting
@@ -363,6 +373,26 @@
                 }
             }
         )
+        initBlurListeners()
+    }
+
+    private fun initBlurListeners() {
+        if (!WindowBlurFlag.isEnabled) return
+
+        applicationScope.launch {
+            Log.d(TAG, "Starting coroutines for window root view blur")
+            windowRootViewBlurInteractor.onBlurAppliedEvent.collect { appliedBlurRadius ->
+                if (updateScheduled) {
+                    // Process the blur applied event only if we scheduled the update
+                    Trace.traceCounter(Trace.TRACE_TAG_APP, "shade_blur_radius", appliedBlurRadius)
+                    updateScheduled = false
+                    onBlurApplied(appliedBlurRadius, zoomOutCalculatedFromShadeRadius)
+                } else {
+                    // Try scheduling an update now, maybe our blur request will be scheduled now.
+                    scheduleUpdate()
+                }
+            }
+        }
     }
 
     private fun updateResources() {
@@ -480,11 +510,17 @@
     }
 
     private fun scheduleUpdate() {
+        val (blur, zoomOutFromShadeRadius) = computeBlurAndZoomOut()
+        zoomOutCalculatedFromShadeRadius = zoomOutFromShadeRadius
+        if (WindowBlurFlag.isEnabled) {
+            updateScheduled =
+                windowRootViewBlurInteractor.requestBlurForShade(blur, shouldBlurBeOpaque)
+            return
+        }
         if (updateScheduled) {
             return
         }
         updateScheduled = true
-        val (blur, _) = computeBlurAndZoomOut()
         blurUtils.prepareBlur(root.viewRootImpl, blur)
         choreographer.postFrameCallback(updateBlurCallback)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index d523bc1..48cf7a83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -48,6 +48,9 @@
 import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
+import com.android.systemui.statusbar.notification.shared.NotificationMinimalism;
+import com.android.systemui.statusbar.notification.shelf.NotificationShelfBackgroundView;
+import com.android.systemui.statusbar.notification.shelf.NotificationShelfIconContainer;
 import com.android.systemui.statusbar.notification.stack.AmbientState;
 import com.android.systemui.statusbar.notification.stack.AnimationProperties;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
@@ -76,7 +79,11 @@
     private static final SourceType BASE_VALUE = SourceType.from("BaseValue");
     private static final SourceType SHELF_SCROLL = SourceType.from("ShelfScroll");
 
-    private NotificationIconContainer mShelfIcons;
+    @VisibleForTesting
+    public NotificationShelfIconContainer mShelfIcons;
+    // This field hides mBackgroundNormal from super class for short-shelf alignment
+    @VisibleForTesting
+    public NotificationShelfBackgroundView mBackgroundNormal;
     private boolean mHideBackground;
     private int mStatusBarHeight;
     private boolean mEnableNotificationClipping;
@@ -116,6 +123,8 @@
         mShelfIcons.setClipChildren(false);
         mShelfIcons.setClipToPadding(false);
 
+        mBackgroundNormal = (NotificationShelfBackgroundView) super.mBackgroundNormal;
+
         setClipToActualHeight(false);
         setClipChildren(false);
         setClipToPadding(false);
@@ -268,19 +277,37 @@
         }
     }
 
-    private void setActualWidth(float actualWidth) {
+    /**
+     * Set the actual width of the shelf, this will only differ from width for short shelves.
+     */
+    @VisibleForTesting
+    public void setActualWidth(float actualWidth) {
         setBackgroundWidth((int) actualWidth);
         if (mShelfIcons != null) {
+            mShelfIcons.setAlignToEnd(isAlignedToEnd());
             mShelfIcons.setActualLayoutWidth((int) actualWidth);
         }
         mActualWidth = actualWidth;
     }
 
     @Override
+    public void setBackgroundWidth(int width) {
+        super.setBackgroundWidth(width);
+        if (!NotificationMinimalism.isEnabled()) {
+            return;
+        }
+        if (mBackgroundNormal != null) {
+            mBackgroundNormal.setAlignToEnd(isAlignedToEnd());
+        }
+    }
+
+    @Override
     public void getBoundsOnScreen(Rect outRect, boolean clipToParent) {
         super.getBoundsOnScreen(outRect, clipToParent);
         final int actualWidth = getActualWidth();
-        if (isLayoutRtl()) {
+        final boolean alignedToRight = NotificationMinimalism.isEnabled() ? isAlignedToRight() :
+                isLayoutRtl();
+        if (alignedToRight) {
             outRect.left = outRect.right - actualWidth;
         } else {
             outRect.right = outRect.left + actualWidth;
@@ -326,11 +353,17 @@
      */
     @Override
     public boolean pointInView(float localX, float localY, float slop) {
-        final float containerWidth = getWidth();
-        final float shelfWidth = getActualWidth();
+        final float left, right;
 
-        final float left = isLayoutRtl() ? containerWidth - shelfWidth : 0;
-        final float right = isLayoutRtl() ? containerWidth : shelfWidth;
+        if (NotificationMinimalism.isEnabled()) {
+            left = getShelfLeftBound();
+            right = getShelfRightBound();
+        } else {
+            final float containerWidth = getWidth();
+            final float shelfWidth = getActualWidth();
+            left = isLayoutRtl() ? containerWidth - shelfWidth : 0;
+            right = isLayoutRtl() ? containerWidth : shelfWidth;
+        }
 
         final float top = mClipTopAmount;
         final float bottom = getActualHeight();
@@ -339,10 +372,53 @@
                 && isYInView(localY, slop, top, bottom);
     }
 
+    /**
+     * @return The left boundary of the shelf.
+     */
+    @VisibleForTesting
+    public float getShelfLeftBound() {
+        if (isAlignedToRight()) {
+            return getWidth() - getActualWidth();
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * @return The right boundary of the shelf.
+     */
+    @VisibleForTesting
+    public float getShelfRightBound() {
+        if (isAlignedToRight()) {
+            return getWidth();
+        } else {
+            return getActualWidth();
+        }
+    }
+
+    @VisibleForTesting
+    public boolean isAlignedToRight() {
+        return isAlignedToEnd() ^ isLayoutRtl();
+    }
+
+    /**
+     * When notification minimalism is on, on split shade, we want the notification shelf to align
+     * to the layout end (right for LTR; left for RTL).
+     * @return whether to align with the minimalism split shade style
+     */
+    @VisibleForTesting
+    public boolean isAlignedToEnd() {
+        if (!NotificationMinimalism.isEnabled()) {
+            return false;
+        }
+        return mAmbientState.getUseSplitShade();
+    }
+
     @Override
     public void updateBackgroundColors() {
         super.updateBackgroundColors();
         ColorUpdateLogger colorUpdateLogger = ColorUpdateLogger.getInstance();
+
         if (colorUpdateLogger != null) {
             colorUpdateLogger.logEvent("Shelf.updateBackgroundColors()",
                     "normalBgColor=" + hexColorString(getNormalBgColor())
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
index 85b50d3..de08e38 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
@@ -132,7 +132,7 @@
         private val phoneIcon =
             Icon.Resource(
                 com.android.internal.R.drawable.ic_phone,
-                ContentDescription.Resource(R.string.ongoing_phone_call_content_description),
+                ContentDescription.Resource(R.string.ongoing_call_content_description),
             )
         private val TAG = "CallVM".pad()
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt
index b3dbf29..229cef9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.chips.casttootherdevice.domain.interactor
 
+import android.media.projection.StopReason
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.log.LogBuffer
@@ -65,7 +66,9 @@
 
     /** Stops the currently active MediaRouter cast. */
     fun stopCasting() {
-        activeCastDevice.value?.let { mediaRouterRepository.stopCasting(it) }
+        activeCastDevice.value?.let {
+            mediaRouterRepository.stopCasting(it, StopReason.STOP_PRIVACY_CHIP)
+        }
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
index a7dbb47..bcd8cfa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt
@@ -100,14 +100,14 @@
             )
         }
 
-        if (Flags.promoteNotificationsAutomatically()) {
+        if (
+            Flags.promoteNotificationsAutomatically() &&
+                this.promotedContent.wasPromotedAutomatically
+        ) {
             // When we're promoting notifications automatically, the `when` time set on the
             // notification will likely just be set to the current time, which would cause the chip
             // to always show "now". We don't want early testers to get that experience since it's
             // not what will happen at launch, so just don't show any time.
-            // TODO(b/364653005): Only ignore the `when` time if the notification was
-            //  *automatically* promoted (as opposed to being legitimately promoted by the
-            // criteria). We'll need to track that status somehow.
             return OngoingActivityChipModel.Shown.IconOnly(icon, colors, onClickListener)
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
index f5952f4..0b5e669 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.chips.screenrecord.domain.interactor
 
+import android.media.projection.StopReason
 import com.android.systemui.Flags
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -140,7 +141,7 @@
 
     /** Stops the recording. */
     fun stopRecording() {
-        scope.launch { screenRecordRepository.stopRecording() }
+        scope.launch { screenRecordRepository.stopRecording(StopReason.STOP_PRIVACY_CHIP) }
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
index 0c4c1a7..c40df98 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt
@@ -149,10 +149,9 @@
         // 1. Set up the right visual params.
         with(iconView) {
             id = CUSTOM_ICON_VIEW_ID
-            // TODO(b/354930838): Update the content description to not include "phone" and maybe
-            // include the app name.
+            // TODO(b/354930838): For RON chips, use the app name for the content description.
             contentDescription =
-                context.resources.getString(R.string.ongoing_phone_call_content_description)
+                context.resources.getString(R.string.ongoing_call_content_description)
             tintView(iconTint)
         }
 
@@ -349,14 +348,21 @@
         }
         // Clickable chips need to be a minimum size for accessibility purposes, but let
         // non-clickable chips be smaller.
-        if (chipModel.onClickListener != null) {
-            chipBackgroundView.minimumWidth =
+        val minimumWidth =
+            if (chipModel.onClickListener != null) {
                 chipBackgroundView.context.resources.getDimensionPixelSize(
                     R.dimen.min_clickable_item_size
                 )
-        } else {
-            chipBackgroundView.minimumWidth = 0
-        }
+            } else {
+                0
+            }
+        // The background view needs the minimum width so it only fills the area required (e.g. the
+        // 3-2-1 screen record countdown chip isn't tappable so it should have a small-width
+        // background).
+        chipBackgroundView.minimumWidth = minimumWidth
+        // The root view needs the minimum width so the second chip can hide if there isn't enough
+        // room for the chip -- see [SecondaryOngoingActivityChip].
+        chipView.minimumWidth = minimumWidth
     }
 
     @IdRes private val CUSTOM_ICON_VIEW_ID = R.id.ongoing_activity_chip_custom_icon
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChronometerText.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChronometerText.kt
new file mode 100644
index 0000000..a747abb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/ChronometerText.kt
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2024 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.chips.ui.compose
+
+import android.os.SystemClock
+import android.text.format.DateUtils.formatElapsedTime
+import androidx.compose.material3.LocalTextStyle
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableLongStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.Measurable
+import androidx.compose.ui.layout.MeasureResult
+import androidx.compose.ui.layout.MeasureScope
+import androidx.compose.ui.node.LayoutModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.constrain
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.compose.LocalLifecycleOwner
+import androidx.lifecycle.repeatOnLifecycle
+import kotlinx.coroutines.delay
+
+/** Platform-optimized interface for getting current time */
+fun interface TimeSource {
+    fun getCurrentTime(): Long
+}
+
+/** Holds and manages the state for a Chronometer */
+class ChronometerState(private val timeSource: TimeSource, private val startTimeMillis: Long) {
+    private var currentTimeMillis by mutableLongStateOf(0L)
+    private val elapsedTimeMillis: Long
+        get() = maxOf(0L, currentTimeMillis - startTimeMillis)
+
+    val currentTimeText: String by derivedStateOf { formatElapsedTime(elapsedTimeMillis / 1000) }
+
+    suspend fun run() {
+        while (true) {
+            currentTimeMillis = timeSource.getCurrentTime()
+            val delaySkewMillis = (currentTimeMillis - startTimeMillis) % 1000L
+            delay(1000L - delaySkewMillis)
+        }
+    }
+}
+
+/** Remember and manage the ChronometerState */
+@Composable
+fun rememberChronometerState(timeSource: TimeSource, startTimeMillis: Long): ChronometerState {
+    val state =
+        remember(timeSource, startTimeMillis) { ChronometerState(timeSource, startTimeMillis) }
+    val lifecycleOwner = LocalLifecycleOwner.current
+    LaunchedEffect(lifecycleOwner, timeSource, startTimeMillis) {
+        lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { state.run() }
+    }
+
+    return state
+}
+
+/**
+ * A composable chronometer that displays elapsed time with constrained width. The width of the text
+ * is only allowed to increase. This ensures there is no visual jitter when individual digits in the
+ * text change due to the timer ticking.
+ */
+@Composable
+fun ChronometerText(
+    startTimeMillis: Long,
+    modifier: Modifier = Modifier,
+    color: Color = Color.Unspecified,
+    style: TextStyle = LocalTextStyle.current,
+    timeSource: TimeSource = remember { TimeSource { SystemClock.elapsedRealtime() } },
+) {
+    val state = rememberChronometerState(timeSource, startTimeMillis)
+    Text(
+        text = state.currentTimeText,
+        style = style,
+        color = color,
+        modifier = modifier.neverDecreaseWidth(),
+    )
+}
+
+/** A modifier that ensures the width of the content only increases and never decreases. */
+private fun Modifier.neverDecreaseWidth(): Modifier {
+    return this.then(neverDecreaseWidthElement)
+}
+
+private data object neverDecreaseWidthElement : ModifierNodeElement<NeverDecreaseWidthNode>() {
+    override fun create(): NeverDecreaseWidthNode {
+        return NeverDecreaseWidthNode()
+    }
+
+    override fun update(node: NeverDecreaseWidthNode) {
+        error("This should never be called")
+    }
+}
+
+private class NeverDecreaseWidthNode : Modifier.Node(), LayoutModifierNode {
+    private var minWidth = 0
+
+    override fun MeasureScope.measure(
+        measurable: Measurable,
+        constraints: Constraints,
+    ): MeasureResult {
+        val placeable = measurable.measure(Constraints(minWidth = minWidth).constrain(constraints))
+        val width = placeable.width
+        val height = placeable.height
+
+        minWidth = maxOf(minWidth, width)
+
+        return layout(width, height) { placeable.place(0, 0) }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/view/SecondaryOngoingActivityChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/view/SecondaryOngoingActivityChip.kt
new file mode 100644
index 0000000..f790dc9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/view/SecondaryOngoingActivityChip.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 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.chips.ui.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.FrameLayout
+
+/**
+ * A custom class for the secondary ongoing activity chip. This class will completely hide itself if
+ * there isn't enough room for the mimimum size chip.
+ *
+ * [this.minimumWidth] must be set correctly in order for this class to work.
+ */
+class SecondaryOngoingActivityChip(context: Context, attrs: AttributeSet) :
+    FrameLayout(context, attrs) {
+    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+        if (measuredWidth < this.minimumWidth) {
+            // There isn't enough room to fit even the minimum content required, so hide completely.
+            // Changing visibility ensures that the content description is not read aloud.
+            visibility = GONE
+            setMeasuredDimension(0, 0)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt
index d24edda..d25ca28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/CommandQueueInitializer.kt
@@ -72,7 +72,7 @@
 
     private fun initializeStatusBarForDisplay(displayId: Int, result: RegisterStatusBarResult) {
         if ((result.mTransientBarTypes and WindowInsets.Type.statusBars()) != 0) {
-            statusBarModeRepository.forDisplay(displayId).showTransient()
+            statusBarModeRepository.forDisplay(displayId)?.showTransient()
         }
         val commandQueueCallbacks = commandQueueCallbacksLazy.get()
         commandQueueCallbacks.onSystemBarAttributesChanged(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
index 9e9a38e..b057fb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarStarter.kt
@@ -89,21 +89,26 @@
     }
 
     private fun createAndStartOrchestratorForDisplay(displayId: Int) {
+        val statusBarModeRepository = statusBarModeRepositoryStore.forDisplay(displayId) ?: return
+        val statusBarInitializer = initializerStore.forDisplay(displayId) ?: return
+        val statusBarWindowController =
+            statusBarWindowControllerStore.forDisplay(displayId) ?: return
+        val autoHideController = autoHideControllerStore.forDisplay(displayId) ?: return
         statusBarOrchestratorFactory
             .create(
                 displayId,
                 displayScopeRepository.scopeForDisplay(displayId),
                 statusBarWindowStateRepositoryStore.forDisplay(displayId),
-                statusBarModeRepositoryStore.forDisplay(displayId),
-                initializerStore.forDisplay(displayId),
-                statusBarWindowControllerStore.forDisplay(displayId),
-                autoHideControllerStore.forDisplay(displayId),
+                statusBarModeRepository,
+                statusBarInitializer,
+                statusBarWindowController,
+                autoHideController,
             )
             .start()
     }
 
     private fun createAndStartInitializerForDisplay(displayId: Int) {
-        statusBarInitializerStore.forDisplay(displayId).start()
+        statusBarInitializerStore.forDisplay(displayId)?.start()
     }
 
     private fun startPrivacyDotForDisplay(displayId: Int) {
@@ -111,6 +116,6 @@
             // For the default display, privacy dot is started via ScreenDecorations
             return
         }
-        privacyDotWindowControllerStore.forDisplay(displayId).start()
+        privacyDotWindowControllerStore.forDisplay(displayId)?.start()
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
index 4c54fc4..1e127ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
@@ -20,9 +20,11 @@
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.CoreStartable
 import com.android.systemui.fragments.FragmentHostManager
+import com.android.systemui.plugins.DarkIconDispatcher
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.core.StatusBarInitializer.OnStatusBarViewInitializedListener
 import com.android.systemui.statusbar.core.StatusBarInitializer.OnStatusBarViewUpdatedListener
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController
 import com.android.systemui.statusbar.data.repository.StatusBarModePerDisplayRepository
 import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions
 import com.android.systemui.statusbar.phone.PhoneStatusBarView
@@ -34,7 +36,6 @@
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
-import java.lang.IllegalStateException
 import javax.inject.Provider
 
 /**
@@ -75,6 +76,8 @@
         fun create(
             statusBarWindowController: StatusBarWindowController,
             statusBarModePerDisplayRepository: StatusBarModePerDisplayRepository,
+            statusBarConfigurationController: StatusBarConfigurationController,
+            darkIconDispatcher: DarkIconDispatcher,
         ): StatusBarInitializer
     }
 }
@@ -84,6 +87,8 @@
 constructor(
     @Assisted private val statusBarWindowController: StatusBarWindowController,
     @Assisted private val statusBarModePerDisplayRepository: StatusBarModePerDisplayRepository,
+    @Assisted private val statusBarConfigurationController: StatusBarConfigurationController,
+    @Assisted private val darkIconDispatcher: DarkIconDispatcher,
     private val collapsedStatusBarFragmentProvider: Provider<CollapsedStatusBarFragment>,
     private val statusBarRootFactory: StatusBarRootFactory,
     private val componentFactory: HomeStatusBarComponent.Factory,
@@ -131,23 +136,32 @@
                 ->
                 val phoneStatusBarView = cv.findViewById<PhoneStatusBarView>(R.id.status_bar)
                 component =
-                    componentFactory.create(phoneStatusBarView).also { component ->
-                        // CollapsedStatusBarFragment used to be responsible initializing
-                        component.init()
-
-                        statusBarViewUpdatedListener?.onStatusBarViewUpdated(
-                            component.phoneStatusBarViewController,
-                            component.phoneStatusBarTransitions,
+                    componentFactory
+                        .create(
+                            phoneStatusBarView,
+                            statusBarConfigurationController,
+                            statusBarWindowController,
+                            darkIconDispatcher,
                         )
+                        .also { component ->
+                            // CollapsedStatusBarFragment used to be responsible initializing
+                            component.init()
 
-                        if (StatusBarConnectedDisplays.isEnabled) {
-                            statusBarModePerDisplayRepository.onStatusBarViewInitialized(component)
-                        } else {
-                            creationListeners.forEach { listener ->
-                                listener.onStatusBarViewInitialized(component)
+                            statusBarViewUpdatedListener?.onStatusBarViewUpdated(
+                                component.phoneStatusBarViewController,
+                                component.phoneStatusBarTransitions,
+                            )
+
+                            if (StatusBarConnectedDisplays.isEnabled) {
+                                statusBarModePerDisplayRepository.onStatusBarViewInitialized(
+                                    component
+                                )
+                            } else {
+                                creationListeners.forEach { listener ->
+                                    listener.onStatusBarViewInitialized(component)
+                                }
                             }
                         }
-                    }
             }
 
         // Add the new compose view to the hierarchy because we don't use fragment transactions
@@ -163,9 +177,11 @@
                 CollapsedStatusBarFragment.TAG,
                 object : FragmentHostManager.FragmentListener {
                     override fun onFragmentViewCreated(tag: String, fragment: Fragment) {
-                        component =
-                            (fragment as CollapsedStatusBarFragment).homeStatusBarComponent
-                                ?: throw IllegalStateException()
+                        val statusBarFragment = fragment as CollapsedStatusBarFragment
+                        if (statusBarFragment.homeStatusBarComponent == null) {
+                            return
+                        }
+                        component = fragment.homeStatusBarComponent
                         statusBarViewUpdatedListener?.onStatusBarViewUpdated(
                             component!!.phoneStatusBarViewController,
                             component!!.phoneStatusBarTransitions,
@@ -195,6 +211,8 @@
         override fun create(
             statusBarWindowController: StatusBarWindowController,
             statusBarModePerDisplayRepository: StatusBarModePerDisplayRepository,
+            statusBarConfigurationController: StatusBarConfigurationController,
+            darkIconDispatcher: DarkIconDispatcher,
         ): StatusBarInitializerImpl
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt
index 4f815c1..de6cd07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializerStore.kt
@@ -22,6 +22,8 @@
 import com.android.systemui.display.data.repository.PerDisplayStore
 import com.android.systemui.display.data.repository.PerDisplayStoreImpl
 import com.android.systemui.display.data.repository.SingleDisplayStore
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore
 import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
 import javax.inject.Inject
@@ -39,6 +41,8 @@
     private val factory: StatusBarInitializer.Factory,
     private val statusBarWindowControllerStore: StatusBarWindowControllerStore,
     private val statusBarModeRepositoryStore: StatusBarModeRepositoryStore,
+    private val statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore,
+    private val darkIconDispatcherStore: DarkIconDispatcherStore,
 ) :
     StatusBarInitializerStore,
     PerDisplayStoreImpl<StatusBarInitializer>(backgroundApplicationScope, displayRepository) {
@@ -47,10 +51,19 @@
         StatusBarConnectedDisplays.assertInNewMode()
     }
 
-    override fun createInstanceForDisplay(displayId: Int): StatusBarInitializer {
+    override fun createInstanceForDisplay(displayId: Int): StatusBarInitializer? {
+        val statusBarWindowController =
+            statusBarWindowControllerStore.forDisplay(displayId) ?: return null
+        val statusBarModePerDisplayRepository =
+            statusBarModeRepositoryStore.forDisplay(displayId) ?: return null
+        val statusBarConfigurationController =
+            statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null
+        val darkIconDispatcher = darkIconDispatcherStore.forDisplay(displayId) ?: return null
         return factory.create(
-            statusBarWindowController = statusBarWindowControllerStore.forDisplay(displayId),
-            statusBarModePerDisplayRepository = statusBarModeRepositoryStore.forDisplay(displayId),
+            statusBarWindowController,
+            statusBarModePerDisplayRepository,
+            statusBarConfigurationController,
+            darkIconDispatcher,
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt
index 8183a48..041f3c8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/DarkIconDispatcherStore.kt
@@ -65,8 +65,9 @@
         StatusBarConnectedDisplays.assertInNewMode()
     }
 
-    override fun createInstanceForDisplay(displayId: Int): SysuiDarkIconDispatcher {
-        val properties = displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR)
+    override fun createInstanceForDisplay(displayId: Int): SysuiDarkIconDispatcher? {
+        val properties =
+            displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null
         return factory.create(displayId, properties.context)
     }
 
@@ -103,7 +104,7 @@
     override val defaultDisplay: DarkIconDispatcher
         get() = store.defaultDisplay
 
-    override fun forDisplay(displayId: Int): DarkIconDispatcher = store.forDisplay(displayId)
+    override fun forDisplay(displayId: Int): DarkIconDispatcher? = store.forDisplay(displayId)
 }
 
 @Module
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
index e498755..c629d10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
@@ -49,13 +49,16 @@
     LightBarControllerStore,
     PerDisplayStoreImpl<LightBarController>(backgroundApplicationScope, displayRepository) {
 
-    override fun createInstanceForDisplay(displayId: Int): LightBarController {
+    override fun createInstanceForDisplay(displayId: Int): LightBarController? {
+        val darkIconDispatcher = darkIconDispatcherStore.forDisplay(displayId) ?: return null
+        val statusBarModePerDisplayRepository =
+            statusBarModeRepositoryStore.forDisplay(displayId) ?: return null
         return factory
             .create(
                 displayId,
                 displayScopeRepository.scopeForDisplay(displayId),
-                darkIconDispatcherStore.forDisplay(displayId),
-                statusBarModeRepositoryStore.forDisplay(displayId),
+                darkIconDispatcher,
+                statusBarModePerDisplayRepository,
             )
             .also { it.start() }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
index bd61c44..d48c94b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
@@ -52,11 +52,14 @@
     PrivacyDotViewControllerStore,
     PerDisplayStoreImpl<PrivacyDotViewController>(backgroundApplicationScope, displayRepository) {
 
-    override fun createInstanceForDisplay(displayId: Int): PrivacyDotViewController {
+    override fun createInstanceForDisplay(displayId: Int): PrivacyDotViewController? {
+        val configurationController =
+            statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null
+        val contentInsetsProvider = contentInsetsProviderStore.forDisplay(displayId) ?: return null
         return factory.create(
             displayScopeRepository.scopeForDisplay(displayId),
-            statusBarConfigurationControllerStore.forDisplay(displayId),
-            contentInsetsProviderStore.forDisplay(displayId),
+            configurationController,
+            contentInsetsProvider,
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt
index a1f5655..086cc99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotWindowControllerStore.kt
@@ -58,15 +58,18 @@
         StatusBarConnectedDisplays.assertInNewMode()
     }
 
-    override fun createInstanceForDisplay(displayId: Int): PrivacyDotWindowController {
+    override fun createInstanceForDisplay(displayId: Int): PrivacyDotWindowController? {
         if (displayId == Display.DEFAULT_DISPLAY) {
             throw IllegalArgumentException("This class should only be used for connected displays")
         }
         val displayWindowProperties =
             displayWindowPropertiesRepository.get(displayId, TYPE_NAVIGATION_BAR_PANEL)
+                ?: return null
+        val privacyDotViewController =
+            privacyDotViewControllerStore.forDisplay(displayId) ?: return null
         return windowControllerFactory.create(
             displayId = displayId,
-            privacyDotViewController = privacyDotViewControllerStore.forDisplay(displayId),
+            privacyDotViewController = privacyDotViewController,
             viewCaptureAwareWindowManager =
                 viewCaptureAwareWindowManagerFactory.create(displayWindowProperties.windowManager),
             inflater = displayWindowProperties.layoutInflater,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt
index 6cf2c73..38cea83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarConfigurationControllerStore.kt
@@ -62,9 +62,9 @@
         StatusBarConnectedDisplays.assertInNewMode()
     }
 
-    override fun createInstanceForDisplay(displayId: Int): StatusBarConfigurationController {
+    override fun createInstanceForDisplay(displayId: Int): StatusBarConfigurationController? {
         val displayWindowProperties =
-            displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR)
+            displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null
         return configurationControllerFactory.create(displayWindowProperties.context)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt
index e471b12..554c46f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarContentInsetsProviderStore.kt
@@ -59,13 +59,17 @@
         displayRepository,
     ) {
 
-    override fun createInstanceForDisplay(displayId: Int): StatusBarContentInsetsProvider {
-        val context = displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR).context
+    override fun createInstanceForDisplay(displayId: Int): StatusBarContentInsetsProvider? {
+        val displayWindowProperties =
+            displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null
+        val context = displayWindowProperties.context
+        val configurationController =
+            statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null
         val cameraProtectionLoader = cameraProtectionLoaderFactory.create(context)
         return factory
             .create(
                 context,
-                statusBarConfigurationControllerStore.forDisplay(displayId),
+                configurationController,
                 sysUICutoutProviderFactory.create(context, cameraProtectionLoader),
             )
             .also { it.start() }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt
index 7760f58..ffc1255 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/SystemEventChipAnimationControllerStore.kt
@@ -62,11 +62,17 @@
         StatusBarConnectedDisplays.assertInNewMode()
     }
 
-    override fun createInstanceForDisplay(displayId: Int): SystemEventChipAnimationController {
+    override fun createInstanceForDisplay(displayId: Int): SystemEventChipAnimationController? {
+        val displayWindowProperties =
+            displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null
+        val statusBarWindowController =
+            statusBarWindowControllerStore.forDisplay(displayId) ?: return null
+        val contentInsetsProvider =
+            statusBarContentInsetsProviderStore.forDisplay(displayId) ?: return null
         return factory.create(
-            displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR).context,
-            statusBarWindowControllerStore.forDisplay(displayId),
-            statusBarContentInsetsProviderStore.forDisplay(displayId),
+            displayWindowProperties.context,
+            statusBarWindowController,
+            contentInsetsProvider,
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt
index f2bb7b1..4b9721e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/MultiDisplaySystemEventChipAnimationController.kt
@@ -72,5 +72,5 @@
     }
 
     private fun controllersForAllDisplays() =
-        displayRepository.displays.value.map { controllerStore.forDisplay(it.displayId) }
+        displayRepository.displays.value.mapNotNull { controllerStore.forDisplay(it.displayId) }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotWindowController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotWindowController.kt
index 9928ac6..f7799bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotWindowController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotWindowController.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.events
 
+import android.util.Log
 import android.view.Display
 import android.view.DisplayCutout.BOUNDS_POSITION_BOTTOM
 import android.view.DisplayCutout.BOUNDS_POSITION_LEFT
@@ -23,6 +24,7 @@
 import android.view.DisplayCutout.BOUNDS_POSITION_TOP
 import android.view.LayoutInflater
 import android.view.View
+import android.view.WindowManager.InvalidDisplayException
 import android.view.WindowManager.LayoutParams.WRAP_CONTENT
 import android.widget.FrameLayout
 import com.android.app.viewcapture.ViewCaptureAwareWindowManager
@@ -97,7 +99,17 @@
         // PrivacyDotViewController expects the dot view to have a FrameLayout parent.
         val rootView = FrameLayout(context)
         rootView.addView(this)
-        viewCaptureAwareWindowManager.addView(rootView, params)
+        try {
+            // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+            // after being added, and initialization hasn't finished yet.
+            viewCaptureAwareWindowManager.addView(rootView, params)
+        } catch (e: InvalidDisplayException) {
+            Log.e(
+                TAG,
+                "Unable to add view to WM. Display with id $displayId does not exist anymore",
+                e,
+            )
+        }
     }
 
     @AssistedFactory
@@ -109,4 +121,8 @@
             inflater: LayoutInflater,
         ): PrivacyDotWindowController
     }
+
+    private companion object {
+        const val TAG = "PrivacyDotWindowController"
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractor.kt
index 85c67f5..4e68bee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractor.kt
@@ -41,14 +41,14 @@
 class MediaControlChipInteractor
 @Inject
 constructor(
-    @Background private val applicationScope: CoroutineScope,
+    @Background private val backgroundScope: CoroutineScope,
     mediaFilterRepository: MediaFilterRepository,
 ) {
     private val currentMediaControls: StateFlow<List<MediaCommonModel.MediaControl>> =
         mediaFilterRepository.currentMedia
             .map { mediaList -> mediaList.filterIsInstance<MediaCommonModel.MediaControl>() }
             .stateIn(
-                scope = applicationScope,
+                scope = backgroundScope,
                 started = SharingStarted.WhileSubscribed(),
                 initialValue = emptyList(),
             )
@@ -64,7 +64,7 @@
                     ?.toMediaControlChipModel()
             }
             .stateIn(
-                scope = applicationScope,
+                scope = backgroundScope,
                 started = SharingStarted.WhileSubscribed(),
                 initialValue = null,
             )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModel.kt
new file mode 100644
index 0000000..3e854b4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModel.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 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.featurepods.media.ui.viewmodel
+
+import android.content.Context
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.statusbar.featurepods.media.domain.interactor.MediaControlChipInteractor
+import com.android.systemui.statusbar.featurepods.media.shared.model.MediaControlChipModel
+import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
+import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
+import com.android.systemui.statusbar.featurepods.popups.ui.viewmodel.StatusBarPopupChipViewModel
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+/**
+ * [StatusBarPopupChipViewModel] for a media control chip in the status bar. This view model is
+ * responsible for converting the [MediaControlChipModel] to a [PopupChipModel] that can be used to
+ * display a media control chip.
+ */
+@SysUISingleton
+class MediaControlChipViewModel
+@Inject
+constructor(
+    @Background private val backgroundScope: CoroutineScope,
+    @Application private val applicationContext: Context,
+    mediaControlChipInteractor: MediaControlChipInteractor,
+) : StatusBarPopupChipViewModel {
+
+    /**
+     * A [StateFlow] of the current [PopupChipModel]. This flow emits a new [PopupChipModel]
+     * whenever the underlying [MediaControlChipModel] changes.
+     */
+    override val chip: StateFlow<PopupChipModel> =
+        mediaControlChipInteractor.mediaControlModel
+            .map { mediaControlModel -> toPopupChipModel(mediaControlModel, applicationContext) }
+            .stateIn(
+                backgroundScope,
+                SharingStarted.WhileSubscribed(),
+                PopupChipModel.Hidden(PopupChipId.MediaControl),
+            )
+}
+
+private fun toPopupChipModel(model: MediaControlChipModel?, context: Context): PopupChipModel {
+    if (model == null || model.songName.isNullOrEmpty()) {
+        return PopupChipModel.Hidden(PopupChipId.MediaControl)
+    }
+
+    val contentDescription = model.appName?.let { ContentDescription.Loaded(description = it) }
+    return PopupChipModel.Shown(
+        chipId = PopupChipId.MediaControl,
+        icon =
+            model.appIcon?.loadDrawable(context)?.let {
+                Icon.Loaded(drawable = it, contentDescription = contentDescription)
+            }
+                ?: Icon.Resource(
+                    res = com.android.internal.R.drawable.ic_audio_media,
+                    contentDescription = contentDescription,
+                ),
+        chipText = model.songName.toString(),
+        // TODO(b/385202114): Show a popup containing the media carousal when the chip is toggled.
+        onToggle = {},
+        // TODO(b/385202193): Add support for clicking on the icon on a media chip.
+        onIconPressed = {},
+    )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt
index 9f523fc..a9f72ff2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/StatusBarPopupChips.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.chips.notification.shared
+package com.android.systemui.statusbar.featurepods.popups
 
 import com.android.systemui.Flags
 import com.android.systemui.flags.FlagToken
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/shared/model/PopupChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/shared/model/PopupChipModel.kt
index 1663aeb..0a6c4d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/shared/model/PopupChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/shared/model/PopupChipModel.kt
@@ -23,7 +23,7 @@
  * displaying its popup at a time.
  */
 sealed class PopupChipId(val value: String) {
-    data object MediaControls : PopupChipId("MediaControls")
+    data object MediaControl : PopupChipId("MediaControl")
 }
 
 /** Model for individual status bar popup chips. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChipsContainer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChipsContainer.kt
new file mode 100644
index 0000000..56bbd74
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/compose/StatusBarPopupChipsContainer.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 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.featurepods.popups.ui.compose
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
+
+/** Container view that holds all right hand side chips in the status bar. */
+@Composable
+fun StatusBarPopupChipsContainer(chips: List<PopupChipModel.Shown>, modifier: Modifier = Modifier) {
+    //    TODO(b/385353140): Add padding and spacing for this container according to UX specs.
+    Box {
+        Row(verticalAlignment = Alignment.CenterVertically) {
+            // TODO(b/385352859): Show `StatusBarPopupChip` here instead of `Text` once it is ready.
+            chips.forEach { chip -> Text(text = chip.chipText) }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModel.kt
index b390f29..caa8e6c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModel.kt
@@ -18,13 +18,16 @@
 
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.statusbar.featurepods.media.ui.viewmodel.MediaControlChipViewModel
+import com.android.systemui.statusbar.featurepods.popups.StatusBarPopupChips
 import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipId
 import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 
@@ -33,16 +36,29 @@
  * PopupChipModels.
  */
 @SysUISingleton
-class StatusBarPopupChipsViewModel @Inject constructor(@Background scope: CoroutineScope) {
+class StatusBarPopupChipsViewModel
+@Inject
+constructor(
+    @Background scope: CoroutineScope,
+    mediaControlChipViewModel: MediaControlChipViewModel,
+) {
     private data class PopupChipBundle(
-        val media: PopupChipModel = PopupChipModel.Hidden(chipId = PopupChipId.MediaControls)
+        val media: PopupChipModel = PopupChipModel.Hidden(chipId = PopupChipId.MediaControl)
     )
 
-    private val incomingPopupChipBundle: Flow<PopupChipBundle?> =
-        flowOf(null).stateIn(scope, SharingStarted.Lazily, PopupChipBundle())
+    private val incomingPopupChipBundle: StateFlow<PopupChipBundle?> =
+        mediaControlChipViewModel.chip
+            .map { chip -> PopupChipBundle(media = chip) }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), PopupChipBundle())
 
-    val popupChips: Flow<List<PopupChipModel>> =
-        incomingPopupChipBundle
-            .map { _ -> listOf(null).filterIsInstance<PopupChipModel.Shown>() }
-            .stateIn(scope, SharingStarted.Lazily, emptyList())
+    val shownPopupChips: StateFlow<List<PopupChipModel.Shown>> =
+        if (StatusBarPopupChips.isEnabled) {
+            incomingPopupChipBundle
+                .map { bundle ->
+                    listOfNotNull(bundle?.media).filterIsInstance<PopupChipModel.Shown>()
+                }
+                .stateIn(scope, SharingStarted.WhileSubscribed(), emptyList())
+        } else {
+            MutableStateFlow(emptyList<PopupChipModel.Shown>()).asStateFlow()
+        }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt
index 227a1fe..eb55856 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/ConnectedDisplaysStatusBarNotificationIconViewStore.kt
@@ -62,8 +62,10 @@
 
     override fun iconView(key: String): StatusBarIconView? {
         val entry = notifCollection.getEntry(key) ?: return null
+        val displayWindowProperties =
+            displayWindowPropertiesInteractor.getForStatusBar(displayId) ?: return null
         return cachedIcons.computeIfAbsent(key) {
-            val context = displayWindowPropertiesInteractor.getForStatusBar(displayId).context
+            val context = displayWindowProperties.context
             iconManager.createSbIconView(context, entry)
         }
     }
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 2ba28a6..e103282 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
@@ -68,13 +68,14 @@
             .distinctUntilChanged()
 
     /** The colors with which to display the notification icons. */
-    fun iconColors(displayId: Int): Flow<NotificationIconColors> =
-        darkIconInteractor
+    fun iconColors(displayId: Int): Flow<NotificationIconColors> {
+        return darkIconInteractor
             .darkState(displayId)
             .map { (areas: Collection<Rect>, tint: Int) -> IconColorsImpl(tint, areas) }
             .flowOn(bgContext)
             .conflate()
             .distinctUntilChanged()
+    }
 
     /** [NotificationIconsViewData] indicating which icons to display in the view. */
     val icons: Flow<NotificationIconsViewData> =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AutomaticPromotionCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AutomaticPromotionCoordinator.kt
index bb16484..3957462 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AutomaticPromotionCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AutomaticPromotionCoordinator.kt
@@ -22,7 +22,16 @@
 import javax.inject.Inject
 
 /** A coordinator that may automatically promote certain notifications. */
-interface AutomaticPromotionCoordinator : Coordinator
+interface AutomaticPromotionCoordinator : Coordinator {
+    companion object {
+        /**
+         * An extra that should be set on notifications that were automatically promoted. Used in
+         * case we want to disable certain features for only automatically promoted notifications
+         * (but not normally promoted notifications).
+         */
+        const val EXTRA_WAS_AUTOMATICALLY_PROMOTED = "android.wasAutomaticallyPromoted"
+    }
+}
 
 /** A default implementation of [AutomaticPromotionCoordinator] that doesn't promote anything. */
 @CoordinatorScope
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
index 7d28276..df2eb08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
@@ -24,14 +24,14 @@
 import android.app.Notification.EXTRA_SUB_TEXT
 import android.app.Notification.EXTRA_TEXT
 import android.app.Notification.EXTRA_TITLE
-import android.app.Notification.FLAG_PROMOTED_ONGOING
 import android.app.Notification.ProgressStyle
 import android.content.Context
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.shade.ShadeDisplayAware
-import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.promoted.AutomaticPromotionCoordinator.Companion.EXTRA_WAS_AUTOMATICALLY_PROMOTED
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
+import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Companion.isPromotedForStatusBarChip
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style
 import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.When
 import javax.inject.Inject
@@ -65,12 +65,8 @@
             return null
         }
 
-        // Notification.isPromotedOngoing checks the ui_rich_ongoing flag, but we want the status
-        // bar chip to be ready before all the features behind the ui_rich_ongoing flag are ready.
-        val isPromotedForStatusBarChip =
-            StatusBarNotifChips.isEnabled && (notification.flags and FLAG_PROMOTED_ONGOING) != 0
-        val isPromoted = notification.isPromotedOngoing() || isPromotedForStatusBarChip
-        if (!isPromoted) {
+        // The status bar chips rely on this extractor, so take them into account for promotion.
+        if (!isPromotedForStatusBarChip(notification)) {
             logger.logExtractionSkipped(entry, "isPromotedOngoing returned false")
             return null
         }
@@ -80,6 +76,8 @@
         // TODO: Pitch a fit if style is unsupported or mandatory fields are missing once
         // FLAG_PROMOTED_ONGOING is set reliably and we're not testing status bar chips.
 
+        contentBuilder.wasPromotedAutomatically =
+            notification.extras.getBoolean(EXTRA_WAS_AUTOMATICALLY_PROMOTED, false)
         contentBuilder.skeletonSmallIcon = entry.icons.aodIcon?.sourceIcon
         contentBuilder.appName = notification.loadHeaderAppName(context)
         contentBuilder.subText = notification.subText()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
index 74809fd..258d80c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
@@ -17,6 +17,8 @@
 package com.android.systemui.statusbar.notification.promoted.shared.model
 
 import android.annotation.DrawableRes
+import android.app.Notification
+import android.app.Notification.FLAG_PROMOTED_ONGOING
 import android.graphics.drawable.Icon
 import androidx.annotation.ColorInt
 import com.android.internal.widget.NotificationProgressModel
@@ -31,6 +33,10 @@
     val identity: Identity,
 
     // for all styles:
+    /**
+     * True if this notification was automatically promoted - see [AutomaticPromotionCoordinator].
+     */
+    val wasPromotedAutomatically: Boolean,
     val skeletonSmallIcon: Icon?, // TODO(b/377568176): Make into an IconModel.
     val appName: CharSequence?,
     val subText: CharSequence?,
@@ -58,6 +64,7 @@
     val progress: NotificationProgressModel?,
 ) {
     class Builder(val key: String) {
+        var wasPromotedAutomatically: Boolean = false
         var skeletonSmallIcon: Icon? = null
         var appName: CharSequence? = null
         var subText: CharSequence? = null
@@ -83,6 +90,7 @@
         fun build() =
             PromotedNotificationContentModel(
                 identity = Identity(key, style),
+                wasPromotedAutomatically = wasPromotedAutomatically,
                 skeletonSmallIcon = skeletonSmallIcon,
                 appName = appName,
                 subText = subText,
@@ -134,5 +142,18 @@
         @JvmStatic
         fun featureFlagEnabled(): Boolean =
             PromotedNotificationUi.isEnabled || StatusBarNotifChips.isEnabled
+
+        /**
+         * Returns true if the given notification should be considered promoted when deciding
+         * whether or not to show the status bar chip UI.
+         */
+        fun isPromotedForStatusBarChip(notification: Notification): Boolean {
+            // Notification.isPromotedOngoing checks the ui_rich_ongoing flag, but we want the
+            // status bar chip to be ready before all the features behind the ui_rich_ongoing flag
+            // are ready.
+            val isPromotedForStatusBarChip =
+                StatusBarNotifChips.isEnabled && (notification.flags and FLAG_PROMOTED_ONGOING) != 0
+            return notification.isPromotedOngoing() || isPromotedForStatusBarChip
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index e440d27..dd3a9c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -169,12 +169,12 @@
                 && !mExpandAnimationRunning) {
             bottom -= mClipBottomAmount;
         }
-        final boolean isRtl = isLayoutRtl();
+        final boolean alignedToRight = isAlignedToRight();
         final int width = getWidth();
         final int actualWidth = getActualWidth();
 
-        int left = isRtl ? width - actualWidth : 0;
-        int right = isRtl ? width : actualWidth;
+        int left = alignedToRight ? width - actualWidth : 0;
+        int right = alignedToRight ? width : actualWidth;
 
         if (mExpandAnimationRunning) {
             // Horizontally center this background view inside of the container
@@ -185,6 +185,15 @@
         return new Rect(left, top, right, bottom);
     }
 
+    /**
+     * @return Whether the background view should be right-aligned. This only matters if the
+     * actualWidth is different than the full (measured) width. In other words, this is used to
+     * define the short-shelf alignment.
+     */
+    protected boolean isAlignedToRight() {
+        return isLayoutRtl();
+    }
+
     private void draw(Canvas canvas, Drawable drawable) {
         NotificationAddXOnHoverToDismiss.assertInLegacyMode();
 
@@ -196,12 +205,13 @@
                     && !mExpandAnimationRunning) {
                 bottom -= mClipBottomAmount;
             }
-            final boolean isRtl = isLayoutRtl();
+
+            final boolean alignedToRight = isAlignedToRight();
             final int width = getWidth();
             final int actualWidth = getActualWidth();
 
-            int left = isRtl ? width - actualWidth : 0;
-            int right = isRtl ? width : actualWidth;
+            int left = alignedToRight ? width - actualWidth : 0;
+            int right = alignedToRight ? width : actualWidth;
 
             if (mExpandAnimationRunning) {
                 // Horizontally center this background view inside of the container
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
index df43ff1..3ccf506 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.row.wrapper;
 
+import static android.app.Flags.notificationsRedesignTemplates;
 import static android.view.View.VISIBLE;
 
 import static com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.DEFAULT_HEADER_VISIBLE_AMOUNT;
@@ -149,10 +150,15 @@
                     }
 
                 }, TRANSFORMING_VIEW_TEXT);
-        mFullHeaderTranslation = ctx.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_content_margin)
-                - ctx.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_content_margin_top);
+        int contentMargin = ctx.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.notification_content_margin);
+        int contentMarginTop =
+                notificationsRedesignTemplates()
+                        ? Notification.Builder.getContentMarginTop(ctx,
+                            com.android.internal.R.dimen.notification_2025_content_margin_top)
+                        : ctx.getResources().getDimensionPixelSize(
+                            com.android.internal.R.dimen.notification_content_margin_top);
+        mFullHeaderTranslation = contentMargin - contentMarginTop;
     }
 
     @MainThread
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/NotificationShelfBackgroundView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/NotificationShelfBackgroundView.kt
new file mode 100644
index 0000000..d7eea01
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/NotificationShelfBackgroundView.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 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.shelf
+
+import android.content.Context
+import android.util.AttributeSet
+import androidx.annotation.VisibleForTesting
+import com.android.systemui.statusbar.notification.row.NotificationBackgroundView
+import com.android.systemui.statusbar.notification.shared.NotificationMinimalism
+
+/** The background view for the NotificationShelf. */
+class NotificationShelfBackgroundView
+@JvmOverloads
+constructor(context: Context, attrs: AttributeSet? = null) :
+    NotificationBackgroundView(context, attrs) {
+
+    /** Whether the notification shelf is aligned to end, need to keep persistent with the shelf. */
+    var alignToEnd = false
+
+    /** @return whether the alignment of the notification shelf is right. */
+    @VisibleForTesting
+    public override fun isAlignedToRight(): Boolean {
+        if (!NotificationMinimalism.isEnabled) {
+            return super.isAlignedToRight()
+        }
+        return alignToEnd xor isLayoutRtl
+    }
+
+    override fun toDumpString(): String {
+        return super.toDumpString() + " alignToEnd=" + alignToEnd
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/NotificationShelfIconContainer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/NotificationShelfIconContainer.kt
new file mode 100644
index 0000000..5106ccc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/NotificationShelfIconContainer.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 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.shelf
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import com.android.internal.annotations.VisibleForTesting
+import com.android.systemui.statusbar.notification.shared.NotificationMinimalism
+import com.android.systemui.statusbar.phone.NotificationIconContainer
+import kotlin.math.max
+
+/** The NotificationIconContainer for the NotificationShelf. */
+class NotificationShelfIconContainer
+@JvmOverloads
+constructor(context: Context, attrs: AttributeSet? = null) :
+    NotificationIconContainer(context, attrs) {
+
+    /** Whether the notification shelf is aligned to end. */
+    var alignToEnd = false
+
+    /**
+     * @return The left boundary (not the RTL compatible start) of the area that icons can be added.
+     */
+    @VisibleForTesting
+    public override fun getLeftBound(): Float {
+        if (!NotificationMinimalism.isEnabled) {
+            return super.getLeftBound()
+        }
+
+        if (isAlignedToRight) {
+            return (max(width - actualWidth, 0) + actualPaddingStart)
+        }
+        return actualPaddingStart
+    }
+
+    /**
+     * @return The right boundary (not the RTL compatible end) of the area that icons can be added.
+     */
+    @VisibleForTesting
+    public override fun getRightBound(): Float {
+        if (!NotificationMinimalism.isEnabled) {
+            return super.getRightBound()
+        }
+
+        if (isAlignedToRight) {
+            return width - actualPaddingEnd
+        }
+        return actualWidth - actualPaddingEnd
+    }
+
+    /**
+     * For RTL, the icons' x positions should be mirrored around the middle of the shelf so that the
+     * icons are also added to the shelf from right to left. This function should only be called
+     * when RTL.
+     */
+    override fun getRtlIconTranslationX(iconState: IconState, iconView: View): Float {
+        if (!NotificationMinimalism.isEnabled) {
+            return super.getRtlIconTranslationX(iconState, iconView)
+        }
+
+        if (!isLayoutRtl) {
+            return iconState.xTranslation
+        }
+
+        if (isAlignedToRight) {
+            return width * 2 - actualWidth - iconState.xTranslation - iconView.width
+        }
+        return actualWidth - iconState.xTranslation - iconView.width
+    }
+
+    @VisibleForTesting
+    val isAlignedToRight: Boolean
+        get() {
+            if (!NotificationMinimalism.isEnabled) {
+                return isLayoutRtl
+            }
+            return alignToEnd xor isLayoutRtl
+        }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 00cd8ce..9fb7fad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -168,8 +168,10 @@
         mDividerHeight = res.getDimensionPixelOffset(
                 R.dimen.notification_children_container_divider_height);
         mDividerAlpha = res.getFloat(R.dimen.notification_divider_alpha);
-        mNotificationHeaderMargin = res.getDimensionPixelOffset(
-                R.dimen.notification_children_container_margin_top);
+        mNotificationHeaderMargin = notificationsRedesignTemplates()
+                ? Notification.Builder.getContentMarginTop(getContext(),
+                    R.dimen.notification_2025_children_container_margin_top)
+                : res.getDimensionPixelOffset(R.dimen.notification_children_container_margin_top);
         mNotificationTopPadding = res.getDimensionPixelOffset(
                 R.dimen.notification_children_container_top_padding);
         mHeaderHeight = notificationsRedesignTemplates()
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 38a7035..50e5a23 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
@@ -866,9 +866,9 @@
             y = (int) mAmbientState.getHeadsUpTop();
             drawDebugInfo(canvas, y, Color.GREEN, /* label= */ "getHeadsUpTop() = " + y);
 
-            y += getTopHeadsUpHeight();
+            y = (int) (mAmbientState.getStackTop() + mScrollViewFields.getIntrinsicStackHeight());
             drawDebugInfo(canvas, y, Color.BLUE,
-                    /* label= */ "getHeadsUpTop() + getTopHeadsUpHeight() = " + y);
+                    /* label= */ "getStackTop() + getIntrinsicStackHeight() = " + y);
 
             return; // the rest of the fields are not important in Flexiglass
         }
@@ -2612,20 +2612,13 @@
         if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
 
         final int shelfIntrinsicHeight = mShelf != null ? mShelf.getIntrinsicHeight() : 0;
-        final int footerIntrinsicHeight =
-                mFooterView != null ? mFooterView.getIntrinsicHeight() : 0;
         final int notificationsHeight = (int) mNotificationStackSizeCalculator.computeHeight(
                 /* notificationStackScrollLayout= */ this,
                 mMaxDisplayedNotifications,
                 shelfIntrinsicHeight
         );
-        // When there is a limit in the max number of notifications, we never display the footer.
-        final int fullStackHeight = mMaxDisplayedNotifications != -1
-                ? notificationsHeight
-                : notificationsHeight + footerIntrinsicHeight + mBottomPadding;
-
-        if (mScrollViewFields.getIntrinsicStackHeight() != fullStackHeight) {
-            mScrollViewFields.setIntrinsicStackHeight(fullStackHeight);
+        if (mScrollViewFields.getIntrinsicStackHeight() != notificationsHeight) {
+            mScrollViewFields.setIntrinsicStackHeight(notificationsHeight);
             notifyStackHeightChangedListeners();
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt
index 744f969..2ae38dd4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt
@@ -47,9 +47,9 @@
         StatusBarConnectedDisplays.assertInNewMode()
     }
 
-    override fun createInstanceForDisplay(displayId: Int): AutoHideController {
+    override fun createInstanceForDisplay(displayId: Int): AutoHideController? {
         val displayWindowProperties =
-            displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR)
+            displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null
         return autoHideControllerFactory.create(displayWindowProperties.context)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
index ea67f1c..ca0c1ac9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarControllerImpl.java
@@ -499,9 +499,9 @@
         /** Creates a {@link LightBarControllerImpl}. */
         LightBarControllerImpl create(
                 int displayId,
-                CoroutineScope coroutineScope,
-                DarkIconDispatcher darkIconDispatcher,
-                StatusBarModePerDisplayRepository statusBarModePerDisplayRepository);
+                @NonNull CoroutineScope coroutineScope,
+                @NonNull DarkIconDispatcher darkIconDispatcher,
+                @NonNull StatusBarModePerDisplayRepository statusBarModePerDisplayRepository);
     }
 
     public static class LegacyFactory implements LightBarController.Factory {
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 ecd62bd..c396512 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -198,7 +198,7 @@
         Paint paint = new Paint();
         paint.setColor(Color.RED);
         paint.setStyle(Paint.Style.STROKE);
-        canvas.drawRect(getActualPaddingStart(), 0, getLayoutEnd(), getHeight(), paint);
+        canvas.drawRect(getActualPaddingStart(), 0, getRightBound(), getHeight(), paint);
 
         if (DEBUG_OVERFLOW) {
             if (mLastVisibleIconState == null) {
@@ -469,11 +469,11 @@
      * If this is not a whole number, the fraction means by how much the icon is appearing.
      */
     public void calculateIconXTranslations() {
-        float translationX = getActualPaddingStart();
+        float translationX = getLeftBound();
         int firstOverflowIndex = -1;
         int childCount = getChildCount();
         int maxVisibleIcons = mMaxIcons;
-        float layoutEnd = getLayoutEnd();
+        float layoutRight = getRightBound();
         mVisualOverflowStart = 0;
         mFirstVisibleIconState = null;
         for (int i = 0; i < childCount; i++) {
@@ -495,7 +495,7 @@
             final boolean forceOverflow = shouldForceOverflow(i, mSpeedBumpIndex,
                     iconState.iconAppearAmount, maxVisibleIcons);
             final boolean isOverflowing = forceOverflow || isOverflowing(
-                    /* isLastChild= */ i == childCount - 1, translationX, layoutEnd, mIconSize);
+                    /* isLastChild= */ i == childCount - 1, translationX, layoutRight, mIconSize);
 
             // First icon to overflow.
             if (firstOverflowIndex == -1 && isOverflowing) {
@@ -536,8 +536,7 @@
             for (int i = 0; i < childCount; i++) {
                 View view = getChildAt(i);
                 IconState iconState = mIconStates.get(view);
-                iconState.setXTranslation(
-                        getWidth() - iconState.getXTranslation() - view.getWidth());
+                iconState.setXTranslation(getRtlIconTranslationX(iconState, view));
             }
         }
         if (mIsolatedIcon != null) {
@@ -553,6 +552,11 @@
         }
     }
 
+    /** We need this to keep icons ordered from right to left when RTL. */
+    protected float getRtlIconTranslationX(IconState iconState, View iconView) {
+        return getWidth() - iconState.getXTranslation() - iconView.getWidth();
+    }
+
     private float getDrawingScale(View view) {
         return mUseIncreasedIconScale && view instanceof StatusBarIconView
                 ? ((StatusBarIconView) view).getIconScaleIncreased()
@@ -563,11 +567,21 @@
         mUseIncreasedIconScale = useIncreasedIconScale;
     }
 
-    private float getLayoutEnd() {
+    /**
+     * @return The right boundary (not the RTL compatible end) of the area that icons can be added.
+     */
+    protected float getRightBound() {
         return getActualWidth() - getActualPaddingEnd();
     }
 
-    private float getActualPaddingEnd() {
+    /**
+     * @return The left boundary (not the RTL compatible start) of the area that icons can be added.
+     */
+    protected float getLeftBound() {
+        return getActualPaddingStart();
+    }
+
+    protected float getActualPaddingEnd() {
         if (mActualPaddingEnd == NO_VALUE) {
             return getPaddingEnd();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt
index 394502b..031754d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusOverlayHoverListener.kt
@@ -33,6 +33,7 @@
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.DarkIconDispatcher
 import com.android.systemui.res.R
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController
 import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore
 import com.android.systemui.statusbar.data.repository.SysuiDarkIconDispatcherStore
 import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange
@@ -54,7 +55,7 @@
 ) {
 
     /** Creates listener always using the same light color for overlay */
-    fun createListener(view: View) =
+    fun createListener(view: View): StatusOverlayHoverListener =
         StatusOverlayHoverListener(
             view,
             configurationController,
@@ -65,8 +66,10 @@
     /**
      * Creates listener using [DarkIconDispatcher] to determine light or dark color of the overlay
      */
-    fun createDarkAwareListener(view: View) =
-        createDarkAwareListener(view, view.darkIconDispatcher.darkChangeFlow())
+    fun createDarkAwareListener(view: View): StatusOverlayHoverListener? {
+        val darkIconDispatcher = view.darkIconDispatcher ?: return null
+        return createDarkAwareListener(view, darkIconDispatcher.darkChangeFlow())
+    }
 
     /**
      * Creates listener using [DarkIconDispatcher] to determine light or dark color of the overlay
@@ -78,27 +81,34 @@
         rightHoverMargin: Int = 0,
         topHoverMargin: Int = 0,
         bottomHoverMargin: Int = 0,
-    ) =
-        createDarkAwareListener(
+    ): StatusOverlayHoverListener? {
+        val darkIconDispatcher = view.darkIconDispatcher ?: return null
+        return createDarkAwareListener(
             view,
-            view.darkIconDispatcher.darkChangeFlow(),
+            darkIconDispatcher.darkChangeFlow(),
             leftHoverMargin,
             rightHoverMargin,
             topHoverMargin,
             bottomHoverMargin,
         )
+    }
 
     /**
      * Creates listener using provided [DarkChange] producer to determine light or dark color of the
      * overlay
      */
-    fun createDarkAwareListener(view: View, darkFlow: StateFlow<DarkChange>) =
-        StatusOverlayHoverListener(
+    fun createDarkAwareListener(
+        view: View,
+        darkFlow: StateFlow<DarkChange>,
+    ): StatusOverlayHoverListener? {
+        val configurationController = view.statusBarConfigurationController ?: return null
+        return StatusOverlayHoverListener(
             view,
-            view.statusBarConfigurationController,
+            configurationController,
             view.resources,
             darkFlow.map { toHoverTheme(view, it) },
         )
+    }
 
     private fun createDarkAwareListener(
         view: View,
@@ -107,10 +117,11 @@
         rightHoverMargin: Int = 0,
         topHoverMargin: Int = 0,
         bottomHoverMargin: Int = 0,
-    ) =
-        StatusOverlayHoverListener(
+    ): StatusOverlayHoverListener? {
+        val configurationController = view.statusBarConfigurationController ?: return null
+        return StatusOverlayHoverListener(
             view,
-            view.statusBarConfigurationController,
+            configurationController,
             view.resources,
             darkFlow.map { toHoverTheme(view, it) },
             leftHoverMargin,
@@ -118,11 +129,12 @@
             topHoverMargin,
             bottomHoverMargin,
         )
+    }
 
-    private val View.statusBarConfigurationController
+    private val View.statusBarConfigurationController: StatusBarConfigurationController?
         get() = statusBarConfigurationControllerStore.forDisplay(context.displayId)
 
-    private val View.darkIconDispatcher
+    private val View.darkIconDispatcher: SysuiDarkIconDispatcher?
         get() = darkIconDispatcherStore.forDisplay(context.displayId)
 
     private fun toHoverTheme(view: View, darkChange: DarkChange): HoverTheme {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
index 4f32aaa26..037dda9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
@@ -31,8 +31,10 @@
 import com.android.systemui.statusbar.core.StatusBarInitializerStore
 import com.android.systemui.statusbar.core.StatusBarOrchestrator
 import com.android.systemui.statusbar.core.StatusBarRootModernization
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore
 import com.android.systemui.statusbar.data.repository.PrivacyDotViewControllerStoreModule
 import com.android.systemui.statusbar.data.repository.PrivacyDotWindowControllerStoreModule
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore
 import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
 import com.android.systemui.statusbar.events.PrivacyDotViewControllerModule
 import com.android.systemui.statusbar.phone.AutoHideControllerStore
@@ -107,10 +109,14 @@
             implFactory: StatusBarInitializerImpl.Factory,
             statusBarWindowControllerStore: StatusBarWindowControllerStore,
             statusBarModeRepositoryStore: StatusBarModeRepositoryStore,
+            statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore,
+            darkIconDispatcherStore: DarkIconDispatcherStore,
         ): StatusBarInitializerImpl {
             return implFactory.create(
                 statusBarWindowControllerStore.defaultDisplay,
                 statusBarModeRepositoryStore.defaultDisplay,
+                statusBarConfigurationControllerStore.defaultDisplay,
+                darkIconDispatcherStore.defaultDisplay,
             )
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/data/repository/DarkIconRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/data/repository/DarkIconRepository.kt
index 49356eb..0464654 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/data/repository/DarkIconRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/data/repository/DarkIconRepository.kt
@@ -15,12 +15,14 @@
  */
 package com.android.systemui.statusbar.phone.data.repository
 
+import android.util.Log
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.statusbar.data.repository.SysuiDarkIconDispatcherStore
 import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher.DarkChange
 import dagger.Binds
 import dagger.Module
 import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 
 /** Dark-mode state for tinting icons. */
@@ -33,8 +35,22 @@
 @Inject
 constructor(private val darkIconDispatcherStore: SysuiDarkIconDispatcherStore) :
     DarkIconRepository {
-    override fun darkState(displayId: Int): StateFlow<DarkChange> =
-        darkIconDispatcherStore.forDisplay(displayId).darkChangeFlow()
+    override fun darkState(displayId: Int): StateFlow<DarkChange> {
+        val perDisplayDakIconDispatcher = darkIconDispatcherStore.forDisplay(displayId)
+        if (perDisplayDakIconDispatcher == null) {
+            Log.e(
+                TAG,
+                "DarkIconDispatcher for display $displayId is null. Returning flow of " +
+                    "DarkChange.EMPTY",
+            )
+            return MutableStateFlow(DarkChange.EMPTY)
+        }
+        return perDisplayDakIconDispatcher.darkChangeFlow()
+    }
+
+    private companion object {
+        const val TAG = "DarkIconRepositoryImpl"
+    }
 }
 
 @Module
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractor.kt
index ed8b3e8..b15fffb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractor.kt
@@ -34,8 +34,8 @@
 @Inject
 constructor(private val repository: StatusBarModeRepositoryStore) {
 
-    fun isLowProfile(displayId: Int): Flow<Boolean> =
-        repository.forDisplay(displayId).statusBarMode.map {
+    fun isLowProfile(displayId: Int): Flow<Boolean>? =
+        repository.forDisplay(displayId)?.statusBarMode?.map {
             when (it) {
                 StatusBarMode.LIGHTS_OUT,
                 StatusBarMode.LIGHTS_OUT_TRANSPARENT -> true
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 d257288..c31e34c5 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
@@ -47,6 +47,7 @@
 import com.android.systemui.demomode.DemoMode;
 import com.android.systemui.demomode.DemoModeController;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.res.R;
 import com.android.systemui.scene.shared.flag.SceneContainerFlag;
@@ -59,6 +60,9 @@
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
 import com.android.systemui.statusbar.core.StatusBarConnectedDisplays;
 import com.android.systemui.statusbar.core.StatusBarRootModernization;
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore;
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController;
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore;
 import com.android.systemui.statusbar.disableflags.DisableFlagsLogger;
 import com.android.systemui.statusbar.events.SystemStatusAnimationCallback;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
@@ -78,6 +82,8 @@
 import com.android.systemui.statusbar.pipeline.shared.ui.binder.StatusBarVisibilityChangeListener;
 import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.window.StatusBarWindowController;
+import com.android.systemui.statusbar.window.StatusBarWindowControllerStore;
 import com.android.systemui.statusbar.window.StatusBarWindowStateController;
 import com.android.systemui.statusbar.window.StatusBarWindowStateListener;
 import com.android.systemui.util.CarrierConfigTracker;
@@ -156,6 +162,9 @@
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final NotificationIconContainerStatusBarViewBinder mNicViewBinder;
     private final DemoModeController mDemoModeController;
+    private final StatusBarWindowControllerStore mStatusBarWindowControllerStore;
+    private final StatusBarConfigurationControllerStore mStatusBarConfigurationControllerStore;
+    private final DarkIconDispatcherStore mDarkIconDispatcherStore;
 
     private List<String> mBlockedIcons = new ArrayList<>();
     private Map<Startable, Startable.State> mStartableStates = new ArrayMap<>();
@@ -263,7 +272,10 @@
             DumpManager dumpManager,
             StatusBarWindowStateController statusBarWindowStateController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
-            DemoModeController demoModeController) {
+            DemoModeController demoModeController,
+            StatusBarWindowControllerStore statusBarWindowControllerStore,
+            StatusBarConfigurationControllerStore statusBarConfigurationControllerStore,
+            DarkIconDispatcherStore darkIconDispatcherStore) {
         mHomeStatusBarComponentFactory = homeStatusBarComponentFactory;
         mOngoingCallController = ongoingCallController;
         mAnimationScheduler = animationScheduler;
@@ -287,6 +299,9 @@
         mStatusBarWindowStateController = statusBarWindowStateController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mDemoModeController = demoModeController;
+        mStatusBarWindowControllerStore = statusBarWindowControllerStore;
+        mStatusBarConfigurationControllerStore = statusBarConfigurationControllerStore;
+        mDarkIconDispatcherStore = darkIconDispatcherStore;
     }
 
     private final DemoMode mDemoModeCallback = new DemoMode() {
@@ -337,8 +352,27 @@
     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
         mDumpManager.registerDumpable(getDumpableName(), this);
-        mHomeStatusBarComponent = mHomeStatusBarComponentFactory.create(
-                (PhoneStatusBarView) getView());
+        int displayId = view.getContext().getDisplayId();
+        StatusBarConfigurationController configurationController =
+                mStatusBarConfigurationControllerStore.forDisplay(displayId);
+        if (configurationController == null) {
+            return;
+        }
+        StatusBarWindowController statusBarWindowController =
+                mStatusBarWindowControllerStore.forDisplay(displayId);
+        if (statusBarWindowController == null) {
+            return;
+        }
+        DarkIconDispatcher darkIconDispatcher = mDarkIconDispatcherStore.forDisplay(displayId);
+        if (darkIconDispatcher == null) {
+            return;
+        }
+        mHomeStatusBarComponent =
+                mHomeStatusBarComponentFactory.create(
+                        (PhoneStatusBarView) getView(),
+                        configurationController,
+                        statusBarWindowController,
+                        darkIconDispatcher);
         mHomeStatusBarComponent.init();
         mStartableStates.clear();
         for (Startable startable : mHomeStatusBarComponent.getStartables()) {
@@ -453,6 +487,9 @@
     @Override
     public void onResume() {
         super.onResume();
+        if (mHomeStatusBarComponent == null) {
+            return;
+        }
         mCommandQueue.addCallback(this);
         mStatusBarStateController.addCallback(this);
         initOngoingCallChip();
@@ -468,6 +505,9 @@
     @Override
     public void onPause() {
         super.onPause();
+        if (mHomeStatusBarComponent == null) {
+            return;
+        }
         mCommandQueue.removeCallback(this);
         mStatusBarStateController.removeCallback(this);
         if (!StatusBarRootModernization.isEnabled()) {
@@ -480,6 +520,9 @@
     @Override
     public void onDestroyView() {
         super.onDestroyView();
+        if (mHomeStatusBarComponent == null) {
+            return;
+        }
         mStatusBarIconController.removeIconGroup(mDarkIconManager);
         mCarrierConfigTracker.removeCallback(mCarrierConfigCallback);
         mCarrierConfigTracker.removeDataSubscriptionChangedListener(mDefaultDataListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarComponent.java
index f8ad0f2..5837752 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarComponent.java
@@ -20,6 +20,7 @@
 import com.android.systemui.dagger.qualifiers.DisplaySpecific;
 import com.android.systemui.dagger.qualifiers.RootView;
 import com.android.systemui.plugins.DarkIconDispatcher;
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController;
 import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.phone.LegacyLightsOutNotifController;
@@ -29,6 +30,7 @@
 import com.android.systemui.statusbar.phone.StatusBarBoundsProvider;
 import com.android.systemui.statusbar.phone.StatusBarDemoMode;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
+import com.android.systemui.statusbar.window.StatusBarWindowController;
 
 import dagger.BindsInstance;
 import dagger.Subcomponent;
@@ -57,7 +59,10 @@
     interface Factory {
         /** */
         HomeStatusBarComponent create(
-                @BindsInstance @RootView PhoneStatusBarView phoneStatusBarView);
+                @BindsInstance @RootView PhoneStatusBarView phoneStatusBarView,
+                @BindsInstance StatusBarConfigurationController configurationController,
+                @BindsInstance StatusBarWindowController statusBarWindowController,
+                @BindsInstance @DisplaySpecific DarkIconDispatcher darkIconDispatcher);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarModule.java
index 182f8d7..6a331b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/HomeStatusBarModule.java
@@ -22,19 +22,14 @@
 import com.android.systemui.battery.BatteryMeterView;
 import com.android.systemui.dagger.qualifiers.DisplaySpecific;
 import com.android.systemui.dagger.qualifiers.RootView;
-import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.HeadsUpStatusBarView;
-import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore;
-import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController;
-import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore;
 import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions;
 import com.android.systemui.statusbar.phone.PhoneStatusBarView;
 import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
 import com.android.systemui.statusbar.phone.StatusBarLocation;
 import com.android.systemui.statusbar.policy.Clock;
 import com.android.systemui.statusbar.window.StatusBarWindowController;
-import com.android.systemui.statusbar.window.StatusBarWindowControllerStore;
 
 import dagger.Module;
 import dagger.Provides;
@@ -149,29 +144,4 @@
     static int displayId(@RootView PhoneStatusBarView view) {
         return view.getContext().getDisplayId();
     }
-
-    /** */
-    @Provides
-    @HomeStatusBarScope
-    static StatusBarConfigurationController configurationController(
-            @DisplaySpecific int displayId, StatusBarConfigurationControllerStore store) {
-        return store.forDisplay(displayId);
-    }
-
-    /** */
-    @Provides
-    @HomeStatusBarScope
-    static StatusBarWindowController provideWindowController(
-            @DisplaySpecific int displayId, StatusBarWindowControllerStore store) {
-        return store.forDisplay(displayId);
-    }
-
-    /** */
-    @Provides
-    @HomeStatusBarScope
-    @DisplaySpecific
-    static DarkIconDispatcher darkIconDispatcher(
-            @DisplaySpecific int displayId, DarkIconDispatcherStore store) {
-        return store.forDisplay(displayId);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
index 2f7b243..2bfbf48 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt
@@ -49,15 +49,18 @@
 /**
  * Interactor for determining whether to show a chip in the status bar for ongoing phone calls.
  *
- * This class monitors call notifications and the visibility of call apps to determine the appropriate
- * chip state. It emits:
- *  * - [OngoingCallModel.NoCall] when there is no call notification
- *  * - [OngoingCallModel.InCallWithVisibleApp] when there is a call notification but the call app is visible
- *  * - [OngoingCallModel.InCall] when there is a call notification and the call app is not visible
- *  */
+ * This class monitors call notifications and the visibility of call apps to determine the
+ * appropriate chip state. It emits:
+ * * - [OngoingCallModel.NoCall] when there is no call notification
+ * * - [OngoingCallModel.InCallWithVisibleApp] when there is a call notification but the call app is
+ *   visible
+ * * - [OngoingCallModel.InCall] when there is a call notification and the call app is not visible
+ */
 @OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
-class OngoingCallInteractor @Inject constructor(
+class OngoingCallInteractor
+@Inject
+constructor(
     @Application private val scope: CoroutineScope,
     private val activityManagerRepository: ActivityManagerRepository,
     private val statusBarModeRepositoryStore: StatusBarModeRepositoryStore,
@@ -68,44 +71,37 @@
 ) : CoreStartable {
     private val logger = Logger(logBuffer, TAG)
 
-    /**
-     * Tracks whether the call chip has been swiped away.
-     */
+    /** Tracks whether the call chip has been swiped away. */
     private val _isChipSwipedAway = MutableStateFlow(false)
     val isChipSwipedAway: StateFlow<Boolean> = _isChipSwipedAway.asStateFlow()
 
-    /**
-     * The current state of ongoing calls.
-     */
+    /** The current state of ongoing calls. */
     val ongoingCallState: StateFlow<OngoingCallModel> =
         activeNotificationsInteractor.ongoingCallNotification
             .flatMapLatest { notification ->
-                createOngoingCallStateFlow(
-                    notification = notification
-                )
+                createOngoingCallStateFlow(notification = notification)
             }
             .stateIn(
                 scope = scope,
                 started = SharingStarted.WhileSubscribed(),
-                initialValue = OngoingCallModel.NoCall
+                initialValue = OngoingCallModel.NoCall,
             )
 
     @VisibleForTesting
-    val isStatusBarRequiredForOngoingCall = combine(
-        ongoingCallState,
-        isChipSwipedAway
-    ) { callState, chipSwipedAway ->
-        callState is OngoingCallModel.InCall && !chipSwipedAway
-    }
+    val isStatusBarRequiredForOngoingCall =
+        combine(ongoingCallState, isChipSwipedAway) { callState, chipSwipedAway ->
+            callState is OngoingCallModel.InCall && !chipSwipedAway
+        }
 
     @VisibleForTesting
-    val isGestureListeningEnabled = combine(
-        ongoingCallState,
-        statusBarModeRepositoryStore.defaultDisplay.isInFullscreenMode,
-        isChipSwipedAway
-    ) { callState, isFullscreen, chipSwipedAway ->
-        callState is OngoingCallModel.InCall && !chipSwipedAway && isFullscreen
-    }
+    val isGestureListeningEnabled =
+        combine(
+            ongoingCallState,
+            statusBarModeRepositoryStore.defaultDisplay.isInFullscreenMode,
+            isChipSwipedAway,
+        ) { callState, isFullscreen, chipSwipedAway ->
+            callState is OngoingCallModel.InCall && !chipSwipedAway && isFullscreen
+        }
 
     private fun createOngoingCallStateFlow(
         notification: ActiveNotificationModel?
@@ -121,7 +117,7 @@
                 creationUid = notification.uid,
                 logger = logger,
                 identifyingLogTag = TAG,
-            )
+            ),
         ) { model, isVisible ->
             deriveOngoingCallState(model, isVisible)
         }
@@ -130,22 +126,19 @@
     override fun start() {
         ongoingCallState
             .filterIsInstance<OngoingCallModel.NoCall>()
-            .onEach {
-                _isChipSwipedAway.value = false
-            }.launchIn(scope)
+            .onEach { _isChipSwipedAway.value = false }
+            .launchIn(scope)
 
-        isStatusBarRequiredForOngoingCall.onEach { statusBarRequired ->
-            setStatusBarRequiredForOngoingCall(statusBarRequired)
-        }.launchIn(scope)
+        isStatusBarRequiredForOngoingCall
+            .onEach { statusBarRequired -> setStatusBarRequiredForOngoingCall(statusBarRequired) }
+            .launchIn(scope)
 
-        isGestureListeningEnabled.onEach { isEnabled ->
-            updateGestureListening(isEnabled)
-        }.launchIn(scope)
+        isGestureListeningEnabled
+            .onEach { isEnabled -> updateGestureListening(isEnabled) }
+            .launchIn(scope)
     }
 
-    /**
-     * Callback that must run when the status bar is swiped while gesture listening is active.
-     */
+    /** Callback that must run when the status bar is swiped while gesture listening is active. */
     @VisibleForTesting
     fun onStatusBarSwiped() {
         logger.d("Status bar chip swiped away")
@@ -154,13 +147,11 @@
 
     private fun deriveOngoingCallState(
         model: ActiveNotificationModel,
-        isVisible: Boolean
+        isVisible: Boolean,
     ): OngoingCallModel {
         return when {
             isVisible -> {
-                logger.d({ "Call app is visible: uid=$int1" }) {
-                    int1 = model.uid
-                }
+                logger.d({ "Call app is visible: uid=$int1" }) { int1 = model.uid }
                 OngoingCallModel.InCallWithVisibleApp
             }
 
@@ -173,7 +164,7 @@
                     startTimeMs = model.whenTime,
                     notificationIconView = model.statusBarChipIconView,
                     intent = model.contentIntent,
-                    notificationKey = model.key
+                    notificationKey = model.key,
                 )
             }
         }
@@ -186,8 +177,9 @@
         statusBarModeRepositoryStore.defaultDisplay.setOngoingProcessRequiresStatusBarVisible(
             statusBarRequired
         )
-        statusBarWindowControllerStore.defaultDisplay
-            .setOngoingProcessRequiresStatusBarVisible(statusBarRequired)
+        statusBarWindowControllerStore.defaultDisplay.setOngoingProcessRequiresStatusBarVisible(
+            statusBarRequired
+        )
     }
 
     private fun updateGestureListening(isEnabled: Boolean) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
index ebf4391..7243ba7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
@@ -19,6 +19,7 @@
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import android.widget.LinearLayout
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxSize
@@ -28,13 +29,17 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.alpha
 import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.ViewCompositionStrategy
 import androidx.compose.ui.viewinterop.AndroidView
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.keyguard.AlphaOptimizedLinearLayout
 import com.android.systemui.plugins.DarkIconDispatcher
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore
 import com.android.systemui.statusbar.events.domain.interactor.SystemStatusEventAnimationInteractor
+import com.android.systemui.statusbar.featurepods.popups.StatusBarPopupChips
+import com.android.systemui.statusbar.featurepods.popups.ui.compose.StatusBarPopupChipsContainer
 import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder
 import com.android.systemui.statusbar.phone.NotificationIconContainer
 import com.android.systemui.statusbar.phone.PhoneStatusBarView
@@ -65,6 +70,8 @@
 ) {
     fun create(root: ViewGroup, andThen: (ViewGroup) -> Unit): ComposeView {
         val composeView = ComposeView(root.context)
+        val darkIconDispatcher =
+            darkIconDispatcherStore.forDisplay(root.context.displayId) ?: return composeView
         composeView.apply {
             setContent {
                 StatusBarRoot(
@@ -75,7 +82,7 @@
                     darkIconManagerFactory = darkIconManagerFactory,
                     iconController = iconController,
                     ongoingCallController = ongoingCallController,
-                    darkIconDispatcher = darkIconDispatcherStore.forDisplay(root.context.displayId),
+                    darkIconDispatcher = darkIconDispatcher,
                     eventAnimationInteractor = eventAnimationInteractor,
                     onViewCreated = andThen,
                 )
@@ -172,6 +179,35 @@
                             R.id.notificationIcons
                         )
 
+                    // Add a composable container for `StatusBarPopupChip`s
+                    if (StatusBarPopupChips.isEnabled) {
+                        val endSideContent =
+                            phoneStatusBarView.requireViewById<AlphaOptimizedLinearLayout>(
+                                R.id.status_bar_end_side_content
+                            )
+
+                        val composeView =
+                            ComposeView(context).apply {
+                                layoutParams =
+                                    LinearLayout.LayoutParams(
+                                        LinearLayout.LayoutParams.WRAP_CONTENT,
+                                        LinearLayout.LayoutParams.WRAP_CONTENT,
+                                    )
+
+                                setViewCompositionStrategy(
+                                    ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
+                                )
+
+                                setContent {
+                                    val chips =
+                                        statusBarViewModel.statusBarPopupChips
+                                            .collectAsStateWithLifecycle()
+                                    StatusBarPopupChipsContainer(chips = chips.value)
+                                }
+                            }
+                        endSideContent.addView(composeView, 0)
+                    }
+
                     scope.launch {
                         notificationIconsBinder.bindWhileAttached(
                             notificationIconContainer,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
index 7f9a80b..c9cc173 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
@@ -42,6 +42,8 @@
 import com.android.systemui.statusbar.events.domain.interactor.SystemStatusEventAnimationInteractor
 import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState
 import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle
+import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
+import com.android.systemui.statusbar.featurepods.popups.ui.viewmodel.StatusBarPopupChipsViewModel
 import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
 import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
 import com.android.systemui.statusbar.notification.headsup.PinnedStatus
@@ -61,6 +63,7 @@
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 
@@ -99,6 +102,9 @@
     /** View model for the carrier name that may show in the status bar based on carrier config */
     val operatorNameViewModel: StatusBarOperatorNameViewModel
 
+    /** The popup chips that should be shown on the right-hand side of the status bar. */
+    val statusBarPopupChips: StateFlow<List<PopupChipModel.Shown>>
+
     /**
      * True if the current scene can show the home status bar (aka this status bar), and false if
      * the current scene should never show the home status bar.
@@ -170,6 +176,7 @@
     sceneContainerOcclusionInteractor: SceneContainerOcclusionInteractor,
     shadeInteractor: ShadeInteractor,
     ongoingActivityChipsViewModel: OngoingActivityChipsViewModel,
+    statusBarPopupChipsViewModel: StatusBarPopupChipsViewModel,
     animations: SystemStatusEventAnimationInteractor,
     @Application coroutineScope: CoroutineScope,
 ) : HomeStatusBarViewModel {
@@ -188,6 +195,8 @@
 
     override val ongoingActivityChips = ongoingActivityChipsViewModel.chips
 
+    override val statusBarPopupChips = statusBarPopupChipsViewModel.shownPopupChips
+
     override val isHomeStatusBarAllowedByScene: StateFlow<Boolean> =
         combine(
                 sceneInteractor.currentScene,
@@ -208,7 +217,7 @@
         } else {
             combine(
                     notificationsInteractor.areAnyNotificationsPresent,
-                    lightsOutInteractor.isLowProfile(displayId),
+                    lightsOutInteractor.isLowProfile(displayId) ?: flowOf(false),
                 ) { hasNotifications, isLowProfile ->
                     hasNotifications && isLowProfile
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
index a3dcc3b..ece5a3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.media.projection.StopReason;
 import com.android.systemui.Dumpable;
 import com.android.systemui.statusbar.policy.CastController.Callback;
 
@@ -26,7 +27,7 @@
     void setCurrentUserId(int currentUserId);
     List<CastDevice> getCastDevices();
     void startCasting(CastDevice device);
-    void stopCasting(CastDevice device);
+    void stopCasting(CastDevice device, @StopReason int stopReason);
 
     /**
      * @return whether we have a connected device.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index 52f80fb..ab20850 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -185,13 +185,13 @@
     }
 
     @Override
-    public void stopCasting(CastDevice device) {
+    public void stopCasting(CastDevice device, @StopReason int stopReason) {
         final boolean isProjection = device.getTag() instanceof MediaProjectionInfo;
         mLogger.logStopCasting(isProjection);
         if (isProjection) {
             final MediaProjectionInfo projection = (MediaProjectionInfo) device.getTag();
             if (Objects.equals(mProjectionManager.getActiveProjectionInfo(), projection)) {
-                mProjectionManager.stopActiveProjection(StopReason.STOP_QS_TILE);
+                mProjectionManager.stopActiveProjection(stopReason);
             } else {
                 mLogger.logStopCastingNoProjection(projection);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
index 811a2ec..848e91d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerImpl.java
@@ -163,7 +163,18 @@
         mLp = getBarLayoutParams(mContext.getDisplay().getRotation());
         Trace.endSection();
 
-        mWindowManager.addView(mStatusBarWindowView, mLp);
+        try {
+            mWindowManager.addView(mStatusBarWindowView, mLp);
+        } catch (WindowManager.InvalidDisplayException e) {
+            // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+            // after being added, and initialization hasn't finished yet.
+            Log.e(
+                    TAG,
+                    "Unable to add view to WindowManager. Display with id "
+                            + mContext.getDisplayId()
+                            + " doesn't exist anymore.",
+                    e);
+        }
         mLpChanged.copyFrom(mLp);
 
         mContentInsetsProvider.addCallback(this::calculateStatusBarLocationsForAllRotations);
@@ -176,7 +187,15 @@
     public void stop() {
         StatusBarConnectedDisplays.assertInNewMode();
 
-        mWindowManager.removeView(mStatusBarWindowView);
+        try {
+            mWindowManager.removeView(mStatusBarWindowView);
+        } catch (IllegalArgumentException e) {
+            // Wrapping this in a try/catch to avoid crashes when a display is instantly removed
+            // after being added, and initialization hasn't finished yet.
+            // When that happens, adding the View to WindowManager fails, and therefore removing
+            // it here will fail too, since it wasn't added in the first place.
+            Log.e(TAG, "Failed to remove View from WindowManager. View was not attached", e);
+        }
 
         if (StatusBarRootModernization.isEnabled()) {
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt
index 7403161..f7688d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowControllerStore.kt
@@ -54,19 +54,23 @@
         StatusBarConnectedDisplays.assertInNewMode()
     }
 
-    override fun createInstanceForDisplay(displayId: Int): StatusBarWindowController {
+    override fun createInstanceForDisplay(displayId: Int): StatusBarWindowController? {
         val statusBarDisplayContext =
             displayWindowPropertiesRepository.get(
                 displayId = displayId,
                 windowType = WindowManager.LayoutParams.TYPE_STATUS_BAR,
-            )
+            ) ?: return null
+        val statusBarConfigurationController =
+            statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null
+        val contentInsetsProvider =
+            statusBarContentInsetsProviderStore.forDisplay(displayId) ?: return null
         val viewCaptureAwareWindowManager =
             viewCaptureAwareWindowManagerFactory.create(statusBarDisplayContext.windowManager)
         return controllerFactory.create(
             statusBarDisplayContext.context,
             viewCaptureAwareWindowManager,
-            statusBarConfigurationControllerStore.forDisplay(displayId),
-            statusBarContentInsetsProviderStore.forDisplay(displayId),
+            statusBarConfigurationController,
+            contentInsetsProvider,
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt
index fbf7072..a6c0665 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.touchpad.tutorial.ui.gesture.VerticalVelocityTracker
 import com.android.systemui.touchpad.tutorial.ui.view.TouchpadTutorialActivity
 import com.android.systemui.touchpad.tutorial.ui.viewmodel.BackGestureScreenViewModel
+import com.android.systemui.touchpad.tutorial.ui.viewmodel.EasterEggGestureViewModel
 import com.android.systemui.touchpad.tutorial.ui.viewmodel.HomeGestureScreenViewModel
 import dagger.Binds
 import dagger.Module
@@ -53,7 +54,11 @@
             backGestureScreenViewModel: BackGestureScreenViewModel,
             homeGestureScreenViewModel: HomeGestureScreenViewModel,
         ): TouchpadTutorialScreensProvider {
-            return ScreensProvider(backGestureScreenViewModel, homeGestureScreenViewModel)
+            return ScreensProvider(
+                backGestureScreenViewModel,
+                homeGestureScreenViewModel,
+                EasterEggGestureViewModel(),
+            )
         }
 
         @SysUISingleton
@@ -74,14 +79,25 @@
 private class ScreensProvider(
     val backGestureScreenViewModel: BackGestureScreenViewModel,
     val homeGestureScreenViewModel: HomeGestureScreenViewModel,
+    val easterEggGestureViewModel: EasterEggGestureViewModel,
 ) : TouchpadTutorialScreensProvider {
     @Composable
     override fun BackGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) {
-        BackGestureTutorialScreen(backGestureScreenViewModel, onDoneButtonClicked, onBack)
+        BackGestureTutorialScreen(
+            backGestureScreenViewModel,
+            easterEggGestureViewModel,
+            onDoneButtonClicked,
+            onBack,
+        )
     }
 
     @Composable
     override fun HomeGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) {
-        HomeGestureTutorialScreen(homeGestureScreenViewModel, onDoneButtonClicked, onBack)
+        HomeGestureTutorialScreen(
+            homeGestureScreenViewModel,
+            easterEggGestureViewModel,
+            onDoneButtonClicked,
+            onBack,
+        )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
index 804a764..ae32b7a 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
@@ -25,10 +25,12 @@
 import com.android.systemui.inputdevice.tutorial.ui.composable.rememberColorFilterProperty
 import com.android.systemui.res.R
 import com.android.systemui.touchpad.tutorial.ui.viewmodel.BackGestureScreenViewModel
+import com.android.systemui.touchpad.tutorial.ui.viewmodel.EasterEggGestureViewModel
 
 @Composable
 fun BackGestureTutorialScreen(
     viewModel: BackGestureScreenViewModel,
+    easterEggGestureViewModel: EasterEggGestureViewModel,
     onDoneButtonClicked: () -> Unit,
     onBack: () -> Unit,
 ) {
@@ -49,9 +51,12 @@
     GestureTutorialScreen(
         screenConfig = screenConfig,
         gestureUiStateFlow = viewModel.gestureUiState,
-        motionEventConsumer = viewModel::handleEvent,
-        easterEggTriggeredFlow = viewModel.easterEggTriggered,
-        onEasterEggFinished = viewModel::onEasterEggFinished,
+        motionEventConsumer = {
+            easterEggGestureViewModel.accept(it)
+            viewModel.handleEvent(it)
+        },
+        easterEggTriggeredFlow = easterEggGestureViewModel.easterEggTriggered,
+        onEasterEggFinished = easterEggGestureViewModel::onEasterEggFinished,
         onDoneButtonClicked = onDoneButtonClicked,
         onBack = onBack,
     )
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
index 5dcd788..4f1f40d 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
@@ -23,11 +23,13 @@
 import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig
 import com.android.systemui.inputdevice.tutorial.ui.composable.rememberColorFilterProperty
 import com.android.systemui.res.R
+import com.android.systemui.touchpad.tutorial.ui.viewmodel.EasterEggGestureViewModel
 import com.android.systemui.touchpad.tutorial.ui.viewmodel.HomeGestureScreenViewModel
 
 @Composable
 fun HomeGestureTutorialScreen(
     viewModel: HomeGestureScreenViewModel,
+    easterEggGestureViewModel: EasterEggGestureViewModel,
     onDoneButtonClicked: () -> Unit,
     onBack: () -> Unit,
 ) {
@@ -48,9 +50,12 @@
     GestureTutorialScreen(
         screenConfig = screenConfig,
         gestureUiStateFlow = viewModel.gestureUiState,
-        motionEventConsumer = viewModel::handleEvent,
-        easterEggTriggeredFlow = viewModel.easterEggTriggered,
-        onEasterEggFinished = viewModel::onEasterEggFinished,
+        motionEventConsumer = {
+            easterEggGestureViewModel.accept(it)
+            viewModel.handleEvent(it)
+        },
+        easterEggTriggeredFlow = easterEggGestureViewModel.easterEggTriggered,
+        onEasterEggFinished = easterEggGestureViewModel::onEasterEggFinished,
         onDoneButtonClicked = onDoneButtonClicked,
         onBack = onBack,
     )
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/RecentAppsGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/RecentAppsGestureTutorialScreen.kt
index 7ff8389..6c9e26c 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/RecentAppsGestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/RecentAppsGestureTutorialScreen.kt
@@ -23,11 +23,13 @@
 import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig
 import com.android.systemui.inputdevice.tutorial.ui.composable.rememberColorFilterProperty
 import com.android.systemui.res.R
+import com.android.systemui.touchpad.tutorial.ui.viewmodel.EasterEggGestureViewModel
 import com.android.systemui.touchpad.tutorial.ui.viewmodel.RecentAppsGestureScreenViewModel
 
 @Composable
 fun RecentAppsGestureTutorialScreen(
     viewModel: RecentAppsGestureScreenViewModel,
+    easterEggGestureViewModel: EasterEggGestureViewModel,
     onDoneButtonClicked: () -> Unit,
     onBack: () -> Unit,
 ) {
@@ -49,9 +51,12 @@
     GestureTutorialScreen(
         screenConfig = screenConfig,
         gestureUiStateFlow = viewModel.gestureUiState,
-        motionEventConsumer = viewModel::handleEvent,
-        easterEggTriggeredFlow = viewModel.easterEggTriggered,
-        onEasterEggFinished = viewModel::onEasterEggFinished,
+        motionEventConsumer = {
+            easterEggGestureViewModel.accept(it)
+            viewModel.handleEvent(it)
+        },
+        easterEggTriggeredFlow = easterEggGestureViewModel.easterEggTriggered,
+        onEasterEggFinished = easterEggGestureViewModel::onEasterEggFinished,
         onDoneButtonClicked = onDoneButtonClicked,
         onBack = onBack,
     )
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureMonitor.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureRecognizer.kt
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureMonitor.kt
rename to packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureRecognizer.kt
index 7483840..18c490b 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureMonitor.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/EasterEggGestureRecognizer.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.touchpad.tutorial.ui.gesture
 
 import android.view.MotionEvent
-import com.android.systemui.touchpad.tutorial.ui.gesture.EasterEggGestureMonitor.Companion.CIRCLES_COUNT_THRESHOLD
+import com.android.systemui.touchpad.tutorial.ui.gesture.EasterEggGestureRecognizer.Companion.CIRCLES_COUNT_THRESHOLD
 import kotlin.math.abs
 import kotlin.math.atan2
 import kotlin.math.pow
@@ -25,10 +25,12 @@
 
 /**
  * Monitor recognizing easter egg gesture, that is at least [CIRCLES_COUNT_THRESHOLD] circles
- * clockwise within one gesture. It tries to be on the safer side of not triggering gesture if we're
- * not sure if full circle was done.
+ * clockwise within one two-fingers gesture. It tries to be on the safer side of not triggering
+ * gesture if we're not sure if full circle was done.
  */
-class EasterEggGestureMonitor(private val callback: () -> Unit) {
+class EasterEggGestureRecognizer : GestureRecognizer {
+
+    private var gestureStateChangedCallback: (GestureState) -> Unit = {}
 
     private var last: Point = Point(0f, 0f)
     private var cumulativeAngle: Float = 0f
@@ -39,7 +41,16 @@
 
     private val points = mutableListOf<Point>()
 
-    fun processTouchpadEvent(event: MotionEvent) {
+    override fun addGestureStateCallback(callback: (GestureState) -> Unit) {
+        gestureStateChangedCallback = callback
+    }
+
+    override fun clearGestureStateCallback() {
+        gestureStateChangedCallback = {}
+    }
+
+    override fun accept(event: MotionEvent) {
+        if (!isTwoFingerSwipe(event)) return
         when (event.action) {
             MotionEvent.ACTION_DOWN -> {
                 reset()
@@ -75,7 +86,7 @@
                 // without checking if gesture is circular we can have gesture doing arches back and
                 // forth that finally reaches full circle angle
                 if (circleCount >= CIRCLES_COUNT_THRESHOLD && wasGestureCircular(points)) {
-                    callback()
+                    gestureStateChangedCallback(GestureState.Finished)
                 }
                 reset()
             }
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadEventsFilter.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadEventsFilter.kt
new file mode 100644
index 0000000..bddeb0b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadEventsFilter.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 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.touchpad.tutorial.ui.gesture
+
+import android.view.InputDevice
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.BUTTON_PRIMARY
+
+object TouchpadEventsFilter {
+
+    fun isTouchpadAndNonClickEvent(event: MotionEvent): Boolean {
+        // events from touchpad have SOURCE_MOUSE and not SOURCE_TOUCHPAD because of legacy reasons
+        val isFromTouchpad =
+            event.isFromSource(InputDevice.SOURCE_MOUSE) &&
+                event.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER
+        val isButtonClicked =
+            event.actionMasked == ACTION_DOWN && event.isButtonPressed(BUTTON_PRIMARY)
+        return isFromTouchpad && !isButtonClicked
+    }
+}
+
+fun GestureRecognizer.handleTouchpadMotionEvent(event: MotionEvent): Boolean {
+    return if (TouchpadEventsFilter.isTouchpadAndNonClickEvent(event)) {
+        this.accept(event)
+        true
+    } else {
+        false
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt
deleted file mode 100644
index dd275bd..0000000
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2024 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.touchpad.tutorial.ui.gesture
-
-import android.view.InputDevice
-import android.view.MotionEvent
-import java.util.function.Consumer
-
-/**
- * Allows listening to touchpadGesture and calling onDone when gesture was triggered. Can have all
- * motion events passed to [onMotionEvent] and will filter touchpad events accordingly
- */
-class TouchpadGestureHandler(
-    private val gestureRecognizer: Consumer<MotionEvent>,
-    private val easterEggGestureMonitor: EasterEggGestureMonitor,
-) {
-
-    fun onMotionEvent(event: MotionEvent): Boolean {
-        // events from touchpad have SOURCE_MOUSE and not SOURCE_TOUCHPAD because of legacy reasons
-        val isFromTouchpad =
-            event.isFromSource(InputDevice.SOURCE_MOUSE) &&
-                event.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER
-        val buttonClick =
-            event.actionMasked == MotionEvent.ACTION_DOWN &&
-                event.isButtonPressed(MotionEvent.BUTTON_PRIMARY)
-        return if (isFromTouchpad && !buttonClick) {
-            if (isTwoFingerSwipe(event)) {
-                easterEggGestureMonitor.processTouchpadEvent(event)
-            }
-            gestureRecognizer.accept(event)
-            true
-        } else {
-            false
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
index 6b4cbab..cefe382 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
@@ -39,6 +39,7 @@
 import com.android.systemui.touchpad.tutorial.ui.composable.RecentAppsGestureTutorialScreen
 import com.android.systemui.touchpad.tutorial.ui.composable.TutorialSelectionScreen
 import com.android.systemui.touchpad.tutorial.ui.viewmodel.BackGestureScreenViewModel
+import com.android.systemui.touchpad.tutorial.ui.viewmodel.EasterEggGestureViewModel
 import com.android.systemui.touchpad.tutorial.ui.viewmodel.HomeGestureScreenViewModel
 import com.android.systemui.touchpad.tutorial.ui.viewmodel.RecentAppsGestureScreenViewModel
 import com.android.systemui.touchpad.tutorial.ui.viewmodel.Screen.BACK_GESTURE
@@ -73,6 +74,7 @@
                     backGestureViewModel,
                     homeGestureViewModel,
                     recentAppsGestureViewModel,
+                    EasterEggGestureViewModel(),
                     closeTutorial = ::finishTutorial,
                 )
             }
@@ -105,6 +107,7 @@
     backGestureViewModel: BackGestureScreenViewModel,
     homeGestureViewModel: HomeGestureScreenViewModel,
     recentAppsGestureViewModel: RecentAppsGestureScreenViewModel,
+    easterEggGestureViewModel: EasterEggGestureViewModel,
     closeTutorial: () -> Unit,
 ) {
     val activeScreen by vm.screen.collectAsStateWithLifecycle(STARTED)
@@ -130,18 +133,21 @@
         BACK_GESTURE ->
             BackGestureTutorialScreen(
                 backGestureViewModel,
+                easterEggGestureViewModel,
                 onDoneButtonClicked = { vm.goTo(TUTORIAL_SELECTION) },
                 onBack = { vm.goTo(TUTORIAL_SELECTION) },
             )
         HOME_GESTURE ->
             HomeGestureTutorialScreen(
                 homeGestureViewModel,
+                easterEggGestureViewModel,
                 onDoneButtonClicked = { vm.goTo(TUTORIAL_SELECTION) },
                 onBack = { vm.goTo(TUTORIAL_SELECTION) },
             )
         RECENT_APPS_GESTURE ->
             RecentAppsGestureTutorialScreen(
                 recentAppsGestureViewModel,
+                easterEggGestureViewModel,
                 onDoneButtonClicked = { vm.goTo(TUTORIAL_SELECTION) },
                 onBack = { vm.goTo(TUTORIAL_SELECTION) },
             )
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModel.kt
index 0154c91..93e8d31 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/BackGestureScreenViewModel.kt
@@ -22,17 +22,15 @@
 import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState
 import com.android.systemui.touchpad.tutorial.ui.composable.toGestureUiState
 import com.android.systemui.touchpad.tutorial.ui.gesture.BackGestureRecognizer
-import com.android.systemui.touchpad.tutorial.ui.gesture.EasterEggGestureMonitor
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureDirection
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureFlowAdapter
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.InProgress
-import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureHandler
+import com.android.systemui.touchpad.tutorial.ui.gesture.handleTouchpadMotionEvent
 import com.android.systemui.util.kotlin.pairwiseBy
 import javax.inject.Inject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flatMapLatest
 
@@ -40,10 +38,7 @@
 @Inject
 constructor(configurationInteractor: ConfigurationInteractor) : TouchpadTutorialScreenViewModel {
 
-    private val easterEggMonitor = EasterEggGestureMonitor { easterEggTriggered.value = true }
-    override val easterEggTriggered = MutableStateFlow(false)
-
-    private var handler: TouchpadGestureHandler? = null
+    private var recognizer: BackGestureRecognizer? = null
 
     private val distanceThreshold: Flow<Int> =
         configurationInteractor
@@ -54,16 +49,15 @@
     override val gestureUiState: Flow<GestureUiState> =
         distanceThreshold
             .flatMapLatest {
-                val recognizer = BackGestureRecognizer(gestureDistanceThresholdPx = it)
-                handler = TouchpadGestureHandler(recognizer, easterEggMonitor)
-                GestureFlowAdapter(recognizer).gestureStateAsFlow
+                recognizer = BackGestureRecognizer(gestureDistanceThresholdPx = it)
+                GestureFlowAdapter(recognizer!!).gestureStateAsFlow
             }
             .pairwiseBy(GestureState.NotStarted) { previous, current ->
                 toGestureUiState(current, previous)
             }
 
     override fun handleEvent(event: MotionEvent): Boolean {
-        return handler?.onMotionEvent(event) ?: false
+        return recognizer?.handleTouchpadMotionEvent(event) ?: false
     }
 
     private fun toGestureUiState(current: GestureState, previous: GestureState): GestureUiState {
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/EasterEggGestureViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/EasterEggGestureViewModel.kt
new file mode 100644
index 0000000..69cdab6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/EasterEggGestureViewModel.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2024 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.touchpad.tutorial.ui.viewmodel
+
+import android.view.MotionEvent
+import com.android.systemui.touchpad.tutorial.ui.gesture.EasterEggGestureRecognizer
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureFlowAdapter
+import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState
+import com.android.systemui.touchpad.tutorial.ui.gesture.handleTouchpadMotionEvent
+import java.util.function.Consumer
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.receiveAsFlow
+
+class EasterEggGestureViewModel(
+    private val gestureRecognizer: EasterEggGestureRecognizer = EasterEggGestureRecognizer()
+) : Consumer<MotionEvent> {
+
+    private val gestureDone =
+        GestureFlowAdapter(gestureRecognizer).gestureStateAsFlow.filter {
+            it == GestureState.Finished
+        }
+
+    private val easterEggFinished = Channel<Unit>()
+
+    val easterEggTriggered =
+        merge(
+                gestureDone.map { Event.GestureFinished },
+                easterEggFinished.receiveAsFlow().map { Event.StateRestarted },
+            )
+            .map {
+                when (it) {
+                    Event.GestureFinished -> true
+                    Event.StateRestarted -> false
+                }
+            }
+            .onStart { emit(false) }
+
+    override fun accept(event: MotionEvent) {
+        gestureRecognizer.handleTouchpadMotionEvent(event)
+    }
+
+    fun onEasterEggFinished() {
+        easterEggFinished.trySend(Unit)
+    }
+
+    private sealed interface Event {
+        data object GestureFinished : Event
+
+        data object StateRestarted : Event
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModel.kt
index 1c865f5..9a817d8 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/HomeGestureScreenViewModel.kt
@@ -23,17 +23,15 @@
 import com.android.systemui.res.R
 import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState
 import com.android.systemui.touchpad.tutorial.ui.composable.toGestureUiState
-import com.android.systemui.touchpad.tutorial.ui.gesture.EasterEggGestureMonitor
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureFlowAdapter
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState
 import com.android.systemui.touchpad.tutorial.ui.gesture.HomeGestureRecognizer
-import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureHandler
 import com.android.systemui.touchpad.tutorial.ui.gesture.VelocityTracker
 import com.android.systemui.touchpad.tutorial.ui.gesture.VerticalVelocityTracker
+import com.android.systemui.touchpad.tutorial.ui.gesture.handleTouchpadMotionEvent
 import javax.inject.Inject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flatMapLatest
@@ -47,10 +45,7 @@
     val velocityTracker: VelocityTracker = VerticalVelocityTracker(),
 ) : TouchpadTutorialScreenViewModel {
 
-    private val easterEggMonitor = EasterEggGestureMonitor { easterEggTriggered.value = true }
-    override val easterEggTriggered = MutableStateFlow(false)
-
-    private var handler: TouchpadGestureHandler? = null
+    private var recognizer: HomeGestureRecognizer? = null
 
     private val distanceThreshold: Flow<Int> =
         configurationInteractor
@@ -67,14 +62,13 @@
         distanceThreshold
             .combine(velocityThreshold, { distance, velocity -> distance to velocity })
             .flatMapLatest { (distance, velocity) ->
-                val recognizer =
+                recognizer =
                     HomeGestureRecognizer(
                         gestureDistanceThresholdPx = distance,
                         velocityThresholdPxPerMs = velocity,
                         velocityTracker = velocityTracker,
                     )
-                handler = TouchpadGestureHandler(recognizer, easterEggMonitor)
-                GestureFlowAdapter(recognizer).gestureStateAsFlow
+                GestureFlowAdapter(recognizer!!).gestureStateAsFlow
             }
             .map { toGestureUiState(it) }
 
@@ -86,6 +80,6 @@
         )
 
     override fun handleEvent(event: MotionEvent): Boolean {
-        return handler?.onMotionEvent(event) ?: false
+        return recognizer?.handleTouchpadMotionEvent(event) ?: false
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModel.kt
index 09947a8..8215078 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/RecentAppsGestureScreenViewModel.kt
@@ -23,17 +23,15 @@
 import com.android.systemui.res.R
 import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState
 import com.android.systemui.touchpad.tutorial.ui.composable.toGestureUiState
-import com.android.systemui.touchpad.tutorial.ui.gesture.EasterEggGestureMonitor
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureFlowAdapter
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState
 import com.android.systemui.touchpad.tutorial.ui.gesture.RecentAppsGestureRecognizer
-import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureHandler
 import com.android.systemui.touchpad.tutorial.ui.gesture.VelocityTracker
 import com.android.systemui.touchpad.tutorial.ui.gesture.VerticalVelocityTracker
+import com.android.systemui.touchpad.tutorial.ui.gesture.handleTouchpadMotionEvent
 import javax.inject.Inject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flatMapLatest
@@ -47,10 +45,7 @@
     private val velocityTracker: VelocityTracker = VerticalVelocityTracker(),
 ) : TouchpadTutorialScreenViewModel {
 
-    private val easterEggMonitor = EasterEggGestureMonitor { easterEggTriggered.value = true }
-    override val easterEggTriggered = MutableStateFlow(false)
-
-    private var handler: TouchpadGestureHandler? = null
+    private var recognizer: RecentAppsGestureRecognizer? = null
 
     private val distanceThreshold: Flow<Int> =
         configurationInteractor.onAnyConfigurationChange
@@ -71,14 +66,13 @@
         distanceThreshold
             .combine(velocityThreshold, { distance, velocity -> distance to velocity })
             .flatMapLatest { (distance, velocity) ->
-                val recognizer =
+                recognizer =
                     RecentAppsGestureRecognizer(
                         gestureDistanceThresholdPx = distance,
                         velocityThresholdPxPerMs = velocity,
                         velocityTracker = velocityTracker,
                     )
-                handler = TouchpadGestureHandler(recognizer, easterEggMonitor)
-                GestureFlowAdapter(recognizer).gestureStateAsFlow
+                GestureFlowAdapter(recognizer!!).gestureStateAsFlow
             }
             .map { toGestureUiState(it) }
 
@@ -90,6 +84,6 @@
         )
 
     override fun handleEvent(event: MotionEvent): Boolean {
-        return handler?.onMotionEvent(event) ?: false
+        return recognizer?.handleTouchpadMotionEvent(event) ?: false
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialScreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialScreenViewModel.kt
index 500f6a0..31e953d 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialScreenViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialScreenViewModel.kt
@@ -19,15 +19,9 @@
 import android.view.MotionEvent
 import com.android.systemui.touchpad.tutorial.ui.composable.GestureUiState
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
 
 interface TouchpadTutorialScreenViewModel {
     val gestureUiState: Flow<GestureUiState>
-    val easterEggTriggered: MutableStateFlow<Boolean>
-
-    fun onEasterEggFinished() {
-        easterEggTriggered.value = false
-    }
 
     fun handleEvent(event: MotionEvent): Boolean
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
index 8bb0279..8733eeb 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/binder/VolumeDialogRingerViewBinder.kt
@@ -71,6 +71,8 @@
 
     fun CoroutineScope.bind(view: View) {
         val volumeDialogBackgroundView = view.requireViewById<View>(R.id.volume_dialog_background)
+        val ringerHBackgroundView =
+            view.requireViewById<View>(R.id.volume_ringer_horizontal_background)
         val drawerContainer = view.requireViewById<MotionLayout>(R.id.volume_ringer_drawer)
         val unselectedButtonUiModel = RingerButtonUiModel.getUnselectedButton(view.context)
         val selectedButtonUiModel = RingerButtonUiModel.getSelectedButton(view.context)
@@ -84,6 +86,11 @@
             )
         var backgroundAnimationProgress: Float by
             Delegates.observable(0F) { _, _, progress ->
+                ringerHBackgroundView.applyCorners(
+                    fullRadius = volumeDialogBgFullRadius,
+                    diff = volumeDialogBgFullRadius - volumeDialogBgSmallRadius,
+                    progress,
+                )
                 volumeDialogBackgroundView.applyCorners(
                     fullRadius = volumeDialogBgFullRadius,
                     diff = volumeDialogBgFullRadius - volumeDialogBgSmallRadius,
@@ -95,6 +102,7 @@
         }
         drawerContainer.setTransitionListener(ringerDrawerTransitionListener)
         volumeDialogBackgroundView.background = volumeDialogBackgroundView.background.mutate()
+        ringerHBackgroundView.background = ringerHBackgroundView.background.mutate()
 
         viewModel.ringerViewModel
             .mapLatest { ringerState ->
@@ -184,6 +192,8 @@
                                 )
                                 volumeDialogBackgroundView.background =
                                     volumeDialogBackgroundView.background.mutate()
+                                ringerHBackgroundView.background =
+                                    ringerHBackgroundView.background.mutate()
                             }
                         }
                     }
@@ -193,6 +203,9 @@
                         volumeDialogBackgroundView.setBackgroundResource(
                             R.drawable.volume_dialog_background
                         )
+                        ringerHBackgroundView.setBackgroundResource(
+                            R.drawable.volume_dialog_background
+                        )
                     }
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/RingerDrawerConstraintsUtils.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/RingerDrawerConstraintsUtils.kt
index 25ba1bd..69ffa38 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/RingerDrawerConstraintsUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/util/RingerDrawerConstraintsUtils.kt
@@ -119,6 +119,15 @@
         )
         when (lastOrientation) {
             ORIENTATION_LANDSCAPE -> {
+                if (index == 0) {
+                    setMargin(
+                        button.id,
+                        ConstraintSet.LEFT,
+                        motionLayout.context.resources.getDimensionPixelSize(
+                            R.dimen.volume_dialog_ringer_drawer_left_margin
+                        ),
+                    )
+                }
                 setButtonPositionLandscapeConstraints(motionLayout, index, button)
                 if (index != motionLayout.childCount - 1) {
                     setMargin(
@@ -134,6 +143,9 @@
                 setMargin(button.id, ConstraintSet.BOTTOM, 0)
             }
             ORIENTATION_PORTRAIT -> {
+                if (index == 0) {
+                    setMargin(button.id, ConstraintSet.LEFT, 0)
+                }
                 setButtonPositionPortraitConstraints(motionLayout, index, button)
                 if (index != motionLayout.childCount - 1) {
                     setMargin(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
index a7ffcd7..67ffb06 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
@@ -16,18 +16,15 @@
 
 package com.android.systemui.volume.dialog.sliders.ui
 
-import android.animation.Animator
-import android.animation.ObjectAnimator
 import android.annotation.SuppressLint
 import android.view.View
-import android.view.animation.DecelerateInterpolator
+import androidx.dynamicanimation.animation.FloatPropertyCompat
+import androidx.dynamicanimation.animation.SpringAnimation
+import androidx.dynamicanimation.animation.SpringForce
 import com.android.systemui.res.R
 import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
 import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderStateModel
 import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderViewModel
-import com.android.systemui.volume.dialog.ui.utils.JankListenerFactory
-import com.android.systemui.volume.dialog.ui.utils.suspendAnimate
-import com.google.android.material.slider.LabelFormatter
 import com.google.android.material.slider.Slider
 import javax.inject.Inject
 import kotlin.math.roundToInt
@@ -35,53 +32,61 @@
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 
-private const val PROGRESS_CHANGE_ANIMATION_DURATION_MS = 80L
-
 @VolumeDialogSliderScope
 class VolumeDialogSliderViewBinder
 @Inject
-constructor(
-    private val viewModel: VolumeDialogSliderViewModel,
-    private val jankListenerFactory: JankListenerFactory,
-) {
+constructor(private val viewModel: VolumeDialogSliderViewModel) {
+
+    private val sliderValueProperty =
+        object : FloatPropertyCompat<Slider>("value") {
+            override fun getValue(slider: Slider): Float = slider.value
+
+            override fun setValue(slider: Slider, value: Float) {
+                slider.value = value
+            }
+        }
+    private val springForce =
+        SpringForce().apply {
+            stiffness = SpringForce.STIFFNESS_MEDIUM
+            dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY
+        }
 
     fun CoroutineScope.bind(view: View) {
-        val sliderView: Slider =
-            view.requireViewById<Slider>(R.id.volume_dialog_slider).apply {
-                labelBehavior = LabelFormatter.LABEL_GONE
-                trackIconActiveColor = trackInactiveTintList
-            }
+        var isInitialUpdate = true
+        val sliderView: Slider = view.requireViewById(R.id.volume_dialog_slider)
+        val animation = SpringAnimation(sliderView, sliderValueProperty)
+        animation.spring = springForce
+
         sliderView.addOnChangeListener { _, value, fromUser ->
             viewModel.setStreamVolume(value.roundToInt(), fromUser)
         }
 
-        viewModel.state.onEach { sliderView.setModel(it) }.launchIn(this)
+        viewModel.state
+            .onEach {
+                sliderView.setModel(it, animation, isInitialUpdate)
+                isInitialUpdate = false
+            }
+            .launchIn(this)
     }
 
     @SuppressLint("UseCompatLoadingForDrawables")
-    private suspend fun Slider.setModel(model: VolumeDialogSliderStateModel) {
+    private fun Slider.setModel(
+        model: VolumeDialogSliderStateModel,
+        animation: SpringAnimation,
+        isInitialUpdate: Boolean,
+    ) {
         valueFrom = model.minValue
+        animation.setMinValue(model.minValue)
         valueTo = model.maxValue
+        animation.setMaxValue(model.maxValue)
         // coerce the current value to the new value range before animating it. This prevents
         // animating from the value that is outside of current [valueFrom, valueTo].
         value = value.coerceIn(valueFrom, valueTo)
-        setValueAnimated(
-            model.value,
-            jankListenerFactory.update(this, PROGRESS_CHANGE_ANIMATION_DURATION_MS),
-        )
-        trackIconActiveEnd = context.getDrawable(model.iconRes)
-    }
-}
-
-private suspend fun Slider.setValueAnimated(
-    newValue: Float,
-    jankListener: Animator.AnimatorListener,
-) {
-    ObjectAnimator.ofFloat(value, newValue)
-        .apply {
-            duration = PROGRESS_CHANGE_ANIMATION_DURATION_MS
-            interpolator = DecelerateInterpolator()
-            addListener(jankListener)
+        setTrackIconActiveStart(model.iconRes)
+        if (isInitialUpdate) {
+            value = model.value
+        } else {
+            animation.animateToFinalPosition(model.value)
         }
-        .suspendAnimate<Float> { value = it }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
index 2d56524..6d8457b 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
@@ -73,19 +73,22 @@
             .filterNotNull()
 
     val state: Flow<VolumeDialogSliderStateModel> =
-        model.flatMapLatest { streamModel ->
-            with(streamModel) {
-                    volumeDialogSliderIconProvider.getStreamIcon(
-                        stream = stream,
-                        level = level,
-                        levelMin = levelMin,
-                        levelMax = levelMax,
-                        isMuted = muted,
-                        isRoutedToBluetooth = routedToBluetooth,
-                    )
-                }
-                .map { icon -> streamModel.toStateModel(icon) }
-        }
+        model
+            .flatMapLatest { streamModel ->
+                with(streamModel) {
+                        volumeDialogSliderIconProvider.getStreamIcon(
+                            stream = stream,
+                            level = level,
+                            levelMin = levelMin,
+                            levelMax = levelMax,
+                            isMuted = muted,
+                            isRoutedToBluetooth = routedToBluetooth,
+                        )
+                    }
+                    .map { icon -> streamModel.toStateModel(icon) }
+            }
+            .stateIn(coroutineScope, SharingStarted.Eagerly, null)
+            .filterNotNull()
 
     init {
         userVolumeUpdates
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/utils/SuspendAnimators.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/utils/SuspendAnimators.kt
index 9b1d86f..52a19e09 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/utils/SuspendAnimators.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ui/utils/SuspendAnimators.kt
@@ -19,6 +19,7 @@
 import android.animation.Animator
 import android.animation.AnimatorListenerAdapter
 import android.animation.ValueAnimator
+import android.animation.ValueAnimator.AnimatorUpdateListener
 import android.view.ViewPropertyAnimator
 import androidx.dynamicanimation.animation.DynamicAnimation
 import androidx.dynamicanimation.animation.SpringAnimation
@@ -69,17 +70,25 @@
 @Suppress("UNCHECKED_CAST")
 suspend fun <T> ValueAnimator.suspendAnimate(onValueChanged: (T) -> Unit) {
     suspendCancellableCoroutine { continuation ->
-        addListener(
+        val listener =
             object : AnimatorListenerAdapter() {
-                override fun onAnimationEnd(animation: Animator) = continuation.resumeIfCan(Unit)
+                    override fun onAnimationEnd(animation: Animator) =
+                        continuation.resumeIfCan(Unit)
 
-                override fun onAnimationCancel(animation: Animator) = continuation.resumeIfCan(Unit)
-            }
-        )
-        addUpdateListener { onValueChanged(it.animatedValue as T) }
+                    override fun onAnimationCancel(animation: Animator) =
+                        continuation.resumeIfCan(Unit)
+                }
+                .also(::addListener)
+        val updateListener =
+            AnimatorUpdateListener { onValueChanged(it.animatedValue as T) }
+                .also(::addUpdateListener)
 
         start()
-        continuation.invokeOnCancellation { cancel() }
+        continuation.invokeOnCancellation {
+            removeUpdateListener(updateListener)
+            removeListener(listener)
+            cancel()
+        }
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepository.kt b/packages/SystemUI/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepository.kt
new file mode 100644
index 0000000..6b7de98
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepository.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 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.window.data.repository
+
+import android.annotation.SuppressLint
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.MutableStateFlow
+
+/** Repository that maintains state for the window blur effect. */
+@SysUISingleton
+class WindowRootViewBlurRepository @Inject constructor() {
+    val blurRadius = MutableStateFlow(0)
+
+    val isBlurOpaque = MutableStateFlow(false)
+
+    @SuppressLint("SharedFlowCreation") val onBlurApplied = MutableSharedFlow<Int>()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractor.kt b/packages/SystemUI/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractor.kt
new file mode 100644
index 0000000..fee32b5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractor.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 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.window.domain.interactor
+
+import android.util.Log
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.window.data.repository.WindowRootViewBlurRepository
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+/**
+ * Interactor that provides the blur state for the window root view
+ * [com.android.systemui.scene.ui.view.WindowRootView]
+ */
+@SysUISingleton
+class WindowRootViewBlurInteractor
+@Inject
+constructor(
+    private val keyguardInteractor: KeyguardInteractor,
+    private val repository: WindowRootViewBlurRepository,
+) {
+
+    /**
+     * Invoked by the view after blur of [appliedBlurRadius] was successfully applied on the window
+     * root view.
+     */
+    suspend fun onBlurApplied(appliedBlurRadius: Int) {
+        repository.onBlurApplied.emit(appliedBlurRadius)
+    }
+
+    /** Radius of blur to be applied on the window root view. */
+    val blurRadius: StateFlow<Int> = repository.blurRadius.asStateFlow()
+
+    /** Whether the blur applied is opaque or transparent. */
+    val isBlurOpaque: StateFlow<Boolean> = repository.isBlurOpaque.asStateFlow()
+
+    /**
+     * Emits the applied blur radius whenever blur is successfully applied to the window root view.
+     */
+    val onBlurAppliedEvent: Flow<Int> = repository.onBlurApplied
+
+    /**
+     * Request to apply blur while on bouncer, this takes precedence over other blurs (from
+     * shade).
+     */
+    fun requestBlurForBouncer(blurRadius: Int) {
+        repository.isBlurOpaque.value = false
+        repository.blurRadius.value = blurRadius
+    }
+
+    /**
+     * Method that requests blur to be applied on window root view. It is applied only when other
+     * blurs are not applied.
+     *
+     * This method is present to temporarily support the blur for notification shade, ideally shade
+     * should expose state that is used by this interactor to determine the blur that has to be
+     * applied.
+     *
+     * @return whether the request for blur was processed or not.
+     */
+    fun requestBlurForShade(blurRadius: Int, opaque: Boolean): Boolean {
+        if (keyguardInteractor.primaryBouncerShowing.value) {
+            return false
+        }
+        Log.d(TAG, "requestingBlurForShade for $blurRadius $opaque")
+        repository.blurRadius.value = blurRadius
+        repository.isBlurOpaque.value = opaque
+        return true
+    }
+
+    companion object {
+        const val TAG = "WindowRootViewBlurInteractor"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt
new file mode 100644
index 0000000..2491ca7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2024 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.window.ui
+
+import android.util.Log
+import android.view.Choreographer
+import android.view.Choreographer.FrameCallback
+import com.android.systemui.lifecycle.WindowLifecycleState
+import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.lifecycle.viewModel
+import com.android.systemui.scene.ui.view.WindowRootView
+import com.android.systemui.statusbar.BlurUtils
+import com.android.systemui.window.flag.WindowBlurFlag
+import com.android.systemui.window.ui.viewmodel.WindowRootViewModel
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.launch
+
+/**
+ * View binder that wires up window level UI transformations like blur to the [WindowRootView]
+ * instance.
+ */
+object WindowRootViewBinder {
+    private const val TAG = "WindowRootViewBinder"
+
+    fun bind(
+        view: WindowRootView,
+        viewModelFactory: WindowRootViewModel.Factory,
+        blurUtils: BlurUtils?,
+        choreographer: Choreographer?,
+    ) {
+        if (!WindowBlurFlag.isEnabled) return
+        if (blurUtils == null || choreographer == null) return
+
+        view.repeatWhenAttached {
+            Log.d(TAG, "Binding root view")
+            var frameCallbackPendingExecution: FrameCallback? = null
+            val viewRootImpl = view.rootView.viewRootImpl
+            view.viewModel(
+                minWindowLifecycleState = WindowLifecycleState.ATTACHED,
+                factory = { viewModelFactory.create() },
+                traceName = "WindowRootViewBinder#bind",
+            ) { viewModel ->
+                try {
+                    Log.d(TAG, "Launching coroutines that update window root view state")
+                    launch {
+                        viewModel.blurState
+                            .filter { it.radius >= 0 }
+                            .collect { blurState ->
+                                val newFrameCallback = FrameCallback {
+                                    frameCallbackPendingExecution = null
+                                    blurUtils.applyBlur(
+                                        viewRootImpl,
+                                        blurState.radius,
+                                        blurState.isOpaque,
+                                    )
+                                    viewModel.onBlurApplied(blurState.radius)
+                                }
+                                blurUtils.prepareBlur(viewRootImpl, blurState.radius)
+                                if (frameCallbackPendingExecution != null) {
+                                    choreographer.removeFrameCallback(frameCallbackPendingExecution)
+                                }
+                                frameCallbackPendingExecution = newFrameCallback
+                                choreographer.postFrameCallback(newFrameCallback)
+                            }
+                    }
+                    awaitCancellation()
+                } finally {
+                    Log.d(TAG, "Wrapped up coroutines that update window root view state")
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt
new file mode 100644
index 0000000..199d02d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2024 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.window.ui.viewmodel
+
+import android.os.Build
+import android.util.Log
+import com.android.app.tracing.coroutines.launchTraced
+import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onEach
+
+typealias BlurAppliedUiEvent = Int
+
+/** View model for window root view. */
+class WindowRootViewModel
+@AssistedInject
+constructor(
+    private val primaryBouncerTransitions: Set<@JvmSuppressWildcards PrimaryBouncerTransition>,
+    private val blurInteractor: WindowRootViewBlurInteractor,
+) : ExclusiveActivatable() {
+
+    private val blurEvents = Channel<BlurAppliedUiEvent>(Channel.BUFFERED)
+    private val _blurState = MutableStateFlow(BlurState(0, false))
+    val blurState = _blurState.asStateFlow()
+
+    override suspend fun onActivated(): Nothing {
+        coroutineScope {
+            launchTraced("WindowRootViewModel#blurEvents") {
+                for (event in blurEvents) {
+                    if (isLoggable) {
+                        Log.d(TAG, "blur applied for $event")
+                    }
+                    blurInteractor.onBlurApplied(event)
+                }
+            }
+
+            launchTraced("WindowRootViewModel#blurState") {
+                combine(blurInteractor.blurRadius, blurInteractor.isBlurOpaque, ::BlurState)
+                    .collect { _blurState.value = it }
+            }
+
+            launchTraced("WindowRootViewModel#bouncerTransitions") {
+                primaryBouncerTransitions
+                    .map { transition ->
+                        transition.windowBlurRadius.onEach { blurRadius ->
+                            if (isLoggable) {
+                                Log.d(
+                                    TAG,
+                                    "${transition.javaClass.simpleName} windowBlurRadius $blurRadius",
+                                )
+                            }
+                        }
+                    }
+                    .merge()
+                    .collect { blurRadius ->
+                        blurInteractor.requestBlurForBouncer(blurRadius.toInt())
+                    }
+            }
+        }
+        awaitCancellation()
+    }
+
+    fun onBlurApplied(blurRadius: Int) {
+        blurEvents.trySend(blurRadius)
+    }
+
+    @AssistedFactory
+    interface Factory {
+        fun create(): WindowRootViewModel
+    }
+
+    private companion object {
+        const val TAG = "WindowRootViewModel"
+        val isLoggable = Log.isLoggable(TAG, Log.DEBUG) || Build.isDebuggable()
+    }
+}
+
+/**
+ * @property radius Radius of blur to be applied on the window root view.
+ * @property isOpaque Whether the blur applied is opaque or transparent.
+ */
+data class BlurState(val radius: Int, val isOpaque: Boolean)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
index 51a7b5f..bc9d4c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
@@ -42,6 +42,7 @@
 import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.systemui.Dependency;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
@@ -95,6 +96,8 @@
     private Lazy<ViewCapture> mLazyViewCapture;
     @Mock
     private NavigationModeController mNavigationModeController;
+    @Mock
+    private HearingAidDeviceManager mHearingAidDeviceManager;
 
     @Before
     public void setUp() throws Exception {
@@ -170,7 +173,7 @@
         mController = setUpController();
         mController.mFloatingMenu = new MenuViewLayerController(mContextWrapper, mWindowManager,
                 mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings,
-                mNavigationModeController);
+                mNavigationModeController, mHearingAidDeviceManager);
         captureKeyguardUpdateMonitorCallback();
         mKeyguardCallback.onUserUnlocked();
 
@@ -198,7 +201,7 @@
         mController = setUpController();
         mController.mFloatingMenu = new MenuViewLayerController(mContextWrapper, mWindowManager,
                 mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings,
-                mNavigationModeController);
+                mNavigationModeController, mHearingAidDeviceManager);
         captureKeyguardUpdateMonitorCallback();
 
         mKeyguardCallback.onUserSwitching(fakeUserId);
@@ -213,7 +216,7 @@
         mController = setUpController();
         mController.mFloatingMenu = new MenuViewLayerController(mContextWrapper, mWindowManager,
                 mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings,
-                mNavigationModeController);
+                mNavigationModeController, mHearingAidDeviceManager);
         captureKeyguardUpdateMonitorCallback();
         mKeyguardCallback.onUserUnlocked();
         mKeyguardCallback.onKeyguardVisibilityChanged(true);
@@ -368,9 +371,9 @@
         final AccessibilityFloatingMenuController controller =
                 new AccessibilityFloatingMenuController(mContextWrapper, windowManager,
                         viewCaptureAwareWindowManager, displayManager, mAccessibilityManager,
-                        mTargetsObserver, mModeObserver, mKeyguardUpdateMonitor, mSecureSettings,
-                        displayTracker, mNavigationModeController, new Handler(
-                                mTestableLooper.getLooper()));
+                        mTargetsObserver, mModeObserver, mHearingAidDeviceManager,
+                        mKeyguardUpdateMonitor, mSecureSettings, displayTracker,
+                        mNavigationModeController, new Handler(mTestableLooper.getLooper()));
         controller.init();
 
         return controller;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java
index dddaabb..856c379 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java
@@ -26,7 +26,6 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.graphics.PointF;
-
 import android.testing.TestableLooper;
 import android.view.View;
 import android.view.ViewPropertyAnimator;
@@ -40,6 +39,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.systemui.Prefs;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.accessibility.utils.TestUtils;
@@ -74,6 +74,8 @@
 
     @Mock
     private AccessibilityManager mAccessibilityManager;
+    @Mock
+    private HearingAidDeviceManager mHearingAidDeviceManager;
 
     @Before
     public void setUp() throws Exception {
@@ -82,7 +84,7 @@
                 stubWindowManager);
         final SecureSettings secureSettings = TestUtils.mockSecureSettings();
         final MenuViewModel stubMenuViewModel = new MenuViewModel(mContext, mAccessibilityManager,
-                secureSettings);
+                secureSettings, mHearingAidDeviceManager);
 
         mMenuView = spy(new MenuView(mContext, stubMenuViewModel, stubMenuViewAppearance,
                 secureSettings));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
index 400b3b3..33cfb38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
@@ -77,6 +77,7 @@
 import com.android.internal.accessibility.common.ShortcutConstants;
 import com.android.internal.accessibility.dialog.AccessibilityTarget;
 import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.settingslib.bluetooth.HearingAidDeviceManager;
 import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.SysuiTestableContext;
@@ -140,6 +141,8 @@
     @Mock
     private AccessibilityManager mStubAccessibilityManager;
     @Mock
+    private HearingAidDeviceManager mHearingAidDeviceManager;
+    @Mock
     private PackageManager mMockPackageManager;
     private final SecureSettings mSecureSettings = TestUtils.mockSecureSettings();
 
@@ -160,7 +163,7 @@
         doReturn(mWindowMetrics).when(mStubWindowManager).getCurrentWindowMetrics();
 
         mMenuViewModel = new MenuViewModel(
-                mSpyContext, mStubAccessibilityManager, mSecureSettings);
+                mSpyContext, mStubAccessibilityManager, mSecureSettings, mHearingAidDeviceManager);
         MenuViewAppearance menuViewAppearance = new MenuViewAppearance(
                 mSpyContext, mStubWindowManager);
         mMenuView = spy(
@@ -419,9 +422,10 @@
     @Test
     @EnableFlags(Flags.FLAG_FLOATING_MENU_DRAG_TO_EDIT)
     public void onDismissAction_incrementsTexMetricDismiss() {
-        mMenuViewModel.onTargetFeaturesChanged(
-                List.of(new TestAccessibilityTarget(mSpyContext, 1234),
-                        new TestAccessibilityTarget(mSpyContext, 5678)));
+        List<AccessibilityTarget> testTargets = new ArrayList<>();
+        testTargets.add(new TestAccessibilityTarget(mSpyContext, 1234));
+        testTargets.add(new TestAccessibilityTarget(mSpyContext, 5678));
+        mMenuViewModel.onTargetFeaturesChanged(testTargets);
 
         mMenuViewLayer.dispatchAccessibilityAction(R.id.action_remove_menu);
 
@@ -431,9 +435,10 @@
     @Test
     @EnableFlags(Flags.FLAG_FLOATING_MENU_DRAG_TO_EDIT)
     public void onEditAction_incrementsTexMetricEdit() {
-        mMenuViewModel.onTargetFeaturesChanged(
-                List.of(new TestAccessibilityTarget(mSpyContext, 1234),
-                        new TestAccessibilityTarget(mSpyContext, 5678)));
+        List<AccessibilityTarget> testTargets = new ArrayList<>();
+        testTargets.add(new TestAccessibilityTarget(mSpyContext, 1234));
+        testTargets.add(new TestAccessibilityTarget(mSpyContext, 5678));
+        mMenuViewModel.onTargetFeaturesChanged(testTargets);
 
         mMenuViewLayer.dispatchAccessibilityAction(R.id.action_edit);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
index 84976a9..0b2b867 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
@@ -32,8 +32,8 @@
 import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.dock.DockManagerFake
-import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.keyguard.data.quickaffordance.BuiltInKeyguardQuickAffordanceKeys
 import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
 import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceProviderClientFactory
@@ -191,10 +191,7 @@
         dockManager = DockManagerFake()
         biometricSettingsRepository = FakeBiometricSettingsRepository()
 
-        val featureFlags =
-            FakeFeatureFlags().apply { set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, false) }
-
-        val withDeps = KeyguardInteractorFactory.create(featureFlags = featureFlags)
+        val withDeps = KeyguardInteractorFactory.create()
         keyguardInteractor = withDeps.keyguardInteractor
         repository = withDeps.repository
 
@@ -287,7 +284,7 @@
                         keyguardStateController = keyguardStateController,
                         userTracker = userTracker,
                         activityStarter = activityStarter,
-                        featureFlags = featureFlags,
+                        featureFlags = kosmos.fakeFeatureFlagsClassic,
                         repository = { quickAffordanceRepository },
                         launchAnimator = launchAnimator,
                         logger = logger,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 47371df..23282b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -27,6 +28,8 @@
 
 import android.app.KeyguardManager;
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.media.AudioManager;
 import android.media.session.MediaController;
@@ -38,6 +41,7 @@
 import android.view.View;
 import android.widget.Button;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import androidx.core.graphics.drawable.IconCompat;
@@ -128,6 +132,21 @@
         when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE);
         mMediaControllers.add(mMediaController);
         when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllers);
+        createMediaSwitchingController(TEST_PACKAGE);
+
+        // Using a fake package will cause routing operations to fail, so we intercept
+        // scanning-related operations.
+        mMediaSwitchingController.mLocalMediaManager = mock(LocalMediaManager.class);
+        doNothing().when(mMediaSwitchingController.mLocalMediaManager).startScan();
+        doNothing().when(mMediaSwitchingController.mLocalMediaManager).stopScan();
+
+        mMediaOutputBaseDialogImpl =
+                new MediaOutputBaseDialogImpl(
+                        mContext, mBroadcastSender, mMediaSwitchingController);
+        mMediaOutputBaseDialogImpl.onCreate(new Bundle());
+    }
+
+    private void createMediaSwitchingController(String testPackage) {
         VolumePanelGlobalStateInteractor volumePanelGlobalStateInteractor =
                 VolumePanelGlobalStateInteractorKosmosKt.getVolumePanelGlobalStateInteractor(
                         mKosmos);
@@ -135,7 +154,7 @@
         mMediaSwitchingController =
                 new MediaSwitchingController(
                         mContext,
-                        TEST_PACKAGE,
+                        testPackage,
                         mContext.getUser(),
                         /* token */ null,
                         mMediaSessionManager,
@@ -150,17 +169,40 @@
                         mFlags,
                         volumePanelGlobalStateInteractor,
                         mUserTracker);
+    }
 
-        // Using a fake package will cause routing operations to fail, so we intercept
-        // scanning-related operations.
-        mMediaSwitchingController.mLocalMediaManager = mock(LocalMediaManager.class);
-        doNothing().when(mMediaSwitchingController.mLocalMediaManager).startScan();
-        doNothing().when(mMediaSwitchingController.mLocalMediaManager).stopScan();
+    @Test
+    public void onCreate_noAppOpenIntent_metadataSectionNonClickable() {
+        createMediaSwitchingController(null);
 
         mMediaOutputBaseDialogImpl =
                 new MediaOutputBaseDialogImpl(
                         mContext, mBroadcastSender, mMediaSwitchingController);
         mMediaOutputBaseDialogImpl.onCreate(new Bundle());
+        final LinearLayout mediaMetadataSectionLayout =
+                mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
+                        R.id.media_metadata_section);
+
+        assertThat(mediaMetadataSectionLayout.isClickable()).isFalse();
+    }
+
+    @Test
+    public void onCreate_appOpenIntentAvailable_metadataSectionClickable() {
+        final PackageManager packageManager = mock(PackageManager.class);
+        mContext.setMockPackageManager(packageManager);
+        Intent intent = new Intent(TEST_PACKAGE);
+        doReturn(intent).when(packageManager).getLaunchIntentForPackage(TEST_PACKAGE);
+        createMediaSwitchingController(TEST_PACKAGE);
+
+        mMediaOutputBaseDialogImpl =
+                new MediaOutputBaseDialogImpl(
+                        mContext, mBroadcastSender, mMediaSwitchingController);
+        mMediaOutputBaseDialogImpl.onCreate(new Bundle());
+        final LinearLayout mediaMetadataSectionLayout =
+                mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
+                        R.id.media_metadata_section);
+
+        assertThat(mediaMetadataSectionLayout.isClickable()).isTrue();
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentControllerTest.java
similarity index 79%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentControllerTest.java
index 782b248..e4a49530 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentControllerTest.java
@@ -9,8 +9,8 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 import static com.android.settingslib.wifi.WifiUtils.getHotspotIconResource;
-import static com.android.systemui.qs.tiles.dialog.InternetDialogController.TOAST_PARAMS_HORIZONTAL_WEIGHT;
-import static com.android.systemui.qs.tiles.dialog.InternetDialogController.TOAST_PARAMS_VERTICAL_WEIGHT;
+import static com.android.systemui.qs.tiles.dialog.InternetDetailsContentController.TOAST_PARAMS_HORIZONTAL_WEIGHT;
+import static com.android.systemui.qs.tiles.dialog.InternetDetailsContentController.TOAST_PARAMS_VERTICAL_WEIGHT;
 import static com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_MAX;
 import static com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_MIN;
 import static com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_UNREACHABLE;
@@ -105,7 +105,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-public class InternetDialogDelegateControllerTest extends SysuiTestCase {
+public class InternetDetailsContentControllerTest extends SysuiTestCase {
 
     private static final int SUB_ID = 1;
     private static final int SUB_ID2 = 2;
@@ -160,7 +160,7 @@
     @Mock
     private WifiUtils.InternetIconInjector mWifiIconInjector;
     @Mock
-    InternetDialogController.InternetDialogCallback mInternetDialogCallback;
+    InternetDetailsContentController.InternetDialogCallback mInternetDialogCallback;
     @Mock
     private ViewCaptureAwareWindowManager mWindowManager;
     @Mock
@@ -189,7 +189,7 @@
     private FakeFeatureFlags mFlags = new FakeFeatureFlags();
 
     private TestableResources mTestableResources;
-    private InternetDialogController mInternetDialogController;
+    private InternetDetailsContentController mInternetDetailsContentController;
     private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
     private List<WifiEntry> mAccessPoints = new ArrayList<>();
     private List<WifiEntry> mWifiEntries = new ArrayList<>();
@@ -229,7 +229,7 @@
         when(mSystemUIToast.getInAnimation()).thenReturn(mAnimator);
         when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
 
-        mInternetDialogController = new InternetDialogController(mContext,
+        mInternetDetailsContentController = new InternetDetailsContentController(mContext,
                 mock(UiEventLogger.class), mock(ActivityStarter.class), mAccessPointController,
                 mSubscriptionManager, mTelephonyManager, mWifiManager,
                 mConnectivityManager, mHandler, mExecutor, mBroadcastDispatcher,
@@ -238,11 +238,11 @@
                 mCarrierConfigTracker, mLocationController, mDialogTransitionAnimator,
                 mWifiStateWorker, mFlags);
         mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor,
-                mInternetDialogController.mOnSubscriptionsChangedListener);
-        mInternetDialogController.onStart(mInternetDialogCallback, true);
-        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
-        mInternetDialogController.mActivityStarter = mActivityStarter;
-        mInternetDialogController.mWifiIconInjector = mWifiIconInjector;
+                mInternetDetailsContentController.mOnSubscriptionsChangedListener);
+        mInternetDetailsContentController.onStart(mInternetDialogCallback, true);
+        mInternetDetailsContentController.onAccessPointsChanged(mAccessPoints);
+        mInternetDetailsContentController.mActivityStarter = mActivityStarter;
+        mInternetDetailsContentController.mWifiIconInjector = mWifiIconInjector;
         mFlags.set(Flags.QS_SECONDARY_DATA_SUB_INFO, false);
         mFlags.set(Flags.SHARE_WIFI_QS_BUTTON, false);
 
@@ -260,7 +260,7 @@
 
     @Test
     public void connectCarrierNetwork_mergedCarrierEntryCanConnect_connectAndCreateSysUiToast() {
-        InternetDialogController spyController = spy(mInternetDialogController);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
         when(spyController.isMobileDataEnabled()).thenReturn(true);
         when(mKeyguardStateController.isUnlocked()).thenReturn(true);
         when(mConnectivityManager.getActiveNetwork()).thenReturn(mNetwork);
@@ -282,7 +282,7 @@
 
     @Test
     public void connectCarrierNetwork_mergedCarrierEntryCanConnect_doNothingWhenSettingsOff() {
-        InternetDialogController spyController = spy(mInternetDialogController);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
         when(spyController.isMobileDataEnabled()).thenReturn(false);
         mTestableResources.addOverride(R.string.wifi_wont_autoconnect_for_now,
             TOAST_MESSAGE_STRING);
@@ -296,7 +296,7 @@
 
     @Test
     public void connectCarrierNetwork_mergedCarrierEntryCanConnect_doNothingWhenKeyguardLocked() {
-        InternetDialogController spyController = spy(mInternetDialogController);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
         when(spyController.isMobileDataEnabled()).thenReturn(true);
         when(mKeyguardStateController.isUnlocked()).thenReturn(false);
 
@@ -311,8 +311,6 @@
 
     @Test
     public void connectCarrierNetwork_mergedCarrierEntryCanConnect_doNothingWhenMobileIsPrimary() {
-        InternetDialogController spyController = spy(mInternetDialogController);
-        when(spyController.isMobileDataEnabled()).thenReturn(true);
         when(mKeyguardStateController.isUnlocked()).thenReturn(true);
         when(mConnectivityManager.getActiveNetwork()).thenReturn(mNetwork);
         when(mConnectivityManager.getNetworkCapabilities(mNetwork))
@@ -322,7 +320,7 @@
 
         mTestableResources.addOverride(R.string.wifi_wont_autoconnect_for_now,
             TOAST_MESSAGE_STRING);
-        mInternetDialogController.connectCarrierNetwork();
+        mInternetDetailsContentController.connectCarrierNetwork();
 
         verify(mMergedCarrierEntry, never()).connect(null /* callback */, false /* showToast */);
         verify(mToastFactory, never()).createToast(any(), any(), anyString(), anyString(), anyInt(),
@@ -333,7 +331,7 @@
     public void makeOverlayToast_withGravityFlags_addViewWithLayoutParams() {
         mTestableResources.addOverride(TOAST_MESSAGE_STRING_ID, TOAST_MESSAGE_STRING);
 
-        mInternetDialogController.makeOverlayToast(TOAST_MESSAGE_STRING_ID);
+        mInternetDetailsContentController.makeOverlayToast(TOAST_MESSAGE_STRING_ID);
 
         ArgumentCaptor<WindowManager.LayoutParams> paramsCaptor = ArgumentCaptor.forClass(
             WindowManager.LayoutParams.class);
@@ -349,7 +347,7 @@
     public void makeOverlayToast_withAnimation_verifyAnimatorStart() {
         mTestableResources.addOverride(TOAST_MESSAGE_STRING_ID, TOAST_MESSAGE_STRING);
 
-        mInternetDialogController.makeOverlayToast(TOAST_MESSAGE_STRING_ID);
+        mInternetDetailsContentController.makeOverlayToast(TOAST_MESSAGE_STRING_ID);
 
         verify(mAnimator).start();
     }
@@ -358,7 +356,7 @@
     public void getDialogTitleText_withAirplaneModeOn_returnAirplaneMode() {
         fakeAirplaneModeEnabled(true);
 
-        assertTrue(TextUtils.equals(mInternetDialogController.getDialogTitleText(),
+        assertTrue(TextUtils.equals(mInternetDetailsContentController.getDialogTitleText(),
                 getResourcesString("airplane_mode")));
     }
 
@@ -366,7 +364,7 @@
     public void getDialogTitleText_withAirplaneModeOff_returnInternet() {
         fakeAirplaneModeEnabled(false);
 
-        assertTrue(TextUtils.equals(mInternetDialogController.getDialogTitleText(),
+        assertTrue(TextUtils.equals(mInternetDetailsContentController.getDialogTitleText(),
                 getResourcesString("quick_settings_internet_label")));
     }
 
@@ -375,13 +373,13 @@
         fakeAirplaneModeEnabled(true);
         when(mWifiStateWorker.isWifiEnabled()).thenReturn(false);
 
-        assertThat(mInternetDialogController.getSubtitleText(false))
+        assertThat(mInternetDetailsContentController.getSubtitleText(false))
                 .isEqualTo(getResourcesString("wifi_is_off"));
 
         // if the Wi-Fi disallow config, then don't return Wi-Fi related string.
-        mInternetDialogController.mCanConfigWifi = false;
+        mInternetDetailsContentController.mCanConfigWifi = false;
 
-        assertThat(mInternetDialogController.getSubtitleText(false))
+        assertThat(mInternetDetailsContentController.getSubtitleText(false))
                 .isNotEqualTo(getResourcesString("wifi_is_off"));
     }
 
@@ -390,13 +388,13 @@
         fakeAirplaneModeEnabled(false);
         when(mWifiStateWorker.isWifiEnabled()).thenReturn(false);
 
-        assertThat(mInternetDialogController.getSubtitleText(false))
+        assertThat(mInternetDetailsContentController.getSubtitleText(false))
                 .isEqualTo(getResourcesString("wifi_is_off"));
 
         // if the Wi-Fi disallow config, then don't return Wi-Fi related string.
-        mInternetDialogController.mCanConfigWifi = false;
+        mInternetDetailsContentController.mCanConfigWifi = false;
 
-        assertThat(mInternetDialogController.getSubtitleText(false))
+        assertThat(mInternetDetailsContentController.getSubtitleText(false))
                 .isNotEqualTo(getResourcesString("wifi_is_off"));
     }
 
@@ -404,15 +402,15 @@
     public void getSubtitleText_withNoWifiEntry_returnSearchWifi() {
         fakeAirplaneModeEnabled(false);
         when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
-        mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
+        mInternetDetailsContentController.onAccessPointsChanged(null /* accessPoints */);
 
-        assertThat(mInternetDialogController.getSubtitleText(true))
+        assertThat(mInternetDetailsContentController.getSubtitleText(true))
                 .isEqualTo(getResourcesString("wifi_empty_list_wifi_on"));
 
         // if the Wi-Fi disallow config, then don't return Wi-Fi related string.
-        mInternetDialogController.mCanConfigWifi = false;
+        mInternetDetailsContentController.mCanConfigWifi = false;
 
-        assertThat(mInternetDialogController.getSubtitleText(true))
+        assertThat(mInternetDetailsContentController.getSubtitleText(true))
                 .isNotEqualTo(getResourcesString("wifi_empty_list_wifi_on"));
     }
 
@@ -422,13 +420,13 @@
         fakeAirplaneModeEnabled(false);
         when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
 
-        assertThat(mInternetDialogController.getSubtitleText(false))
+        assertThat(mInternetDetailsContentController.getSubtitleText(false))
                 .isEqualTo(getResourcesString("tap_a_network_to_connect"));
 
         // if the Wi-Fi disallow config, then don't return Wi-Fi related string.
-        mInternetDialogController.mCanConfigWifi = false;
+        mInternetDetailsContentController.mCanConfigWifi = false;
 
-        assertThat(mInternetDialogController.getSubtitleText(false))
+        assertThat(mInternetDetailsContentController.getSubtitleText(false))
                 .isNotEqualTo(getResourcesString("tap_a_network_to_connect"));
     }
 
@@ -438,14 +436,14 @@
         when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
         when(mKeyguardStateController.isUnlocked()).thenReturn(false);
 
-        assertTrue(TextUtils.equals(mInternetDialogController.getSubtitleText(false),
+        assertTrue(TextUtils.equals(mInternetDetailsContentController.getSubtitleText(false),
                 getResourcesString("unlock_to_view_networks")));
     }
 
     @Test
     public void getSubtitleText_withNoService_returnNoNetworksAvailable() {
         mFlags.set(Flags.QS_SECONDARY_DATA_SUB_INFO, true);
-        InternetDialogController spyController = spy(mInternetDialogController);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
         fakeAirplaneModeEnabled(false);
         when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
         spyController.onAccessPointsChanged(null /* accessPoints */);
@@ -466,7 +464,7 @@
 
     @Test
     public void getSubtitleText_withNoService_returnNoNetworksAvailable_flagOff() {
-        InternetDialogController spyController = spy(mInternetDialogController);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
         fakeAirplaneModeEnabled(false);
         when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
         spyController.onAccessPointsChanged(null /* accessPoints */);
@@ -488,22 +486,22 @@
     public void getSubtitleText_withMobileDataDisabled_returnNoOtherAvailable() {
         fakeAirplaneModeEnabled(false);
         when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
-        mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
-        InternetDialogController spyController = spy(mInternetDialogController);
+        mInternetDetailsContentController.onAccessPointsChanged(null /* accessPoints */);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
 
         doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState();
         spyController.mSubIdServiceState.put(SUB_ID, mServiceState);
 
-        assertThat(mInternetDialogController.getSubtitleText(false))
+        assertThat(mInternetDetailsContentController.getSubtitleText(false))
                 .isEqualTo(getResourcesString("non_carrier_network_unavailable"));
 
         // if the Wi-Fi disallow config, then don't return Wi-Fi related string.
-        mInternetDialogController.mCanConfigWifi = false;
+        mInternetDetailsContentController.mCanConfigWifi = false;
 
         when(spyController.isMobileDataEnabled()).thenReturn(false);
 
 
-        assertThat(mInternetDialogController.getSubtitleText(false))
+        assertThat(mInternetDetailsContentController.getSubtitleText(false))
                 .isNotEqualTo(getResourcesString("non_carrier_network_unavailable"));
     }
 
@@ -511,21 +509,22 @@
     public void getSubtitleText_withCarrierNetworkActiveOnly_returnNoOtherAvailable() {
         fakeAirplaneModeEnabled(false);
         when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
-        mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
+        mInternetDetailsContentController.onAccessPointsChanged(null /* accessPoints */);
         when(mMergedCarrierEntry.isDefaultNetwork()).thenReturn(true);
 
-        assertThat(mInternetDialogController.getSubtitleText(false))
+        assertThat(mInternetDetailsContentController.getSubtitleText(false))
                 .isEqualTo(getResourcesString("non_carrier_network_unavailable"));
     }
 
     @Test
     public void getWifiDetailsSettingsIntent_withNoKey_returnNull() {
-        assertThat(mInternetDialogController.getWifiDetailsSettingsIntent(null)).isNull();
+        assertThat(mInternetDetailsContentController.getWifiDetailsSettingsIntent(null)).isNull();
     }
 
     @Test
     public void getWifiDetailsSettingsIntent_withKey_returnIntent() {
-        assertThat(mInternetDialogController.getWifiDetailsSettingsIntent("test_key")).isNotNull();
+        assertThat(mInternetDetailsContentController.getWifiDetailsSettingsIntent(
+                "test_key")).isNotNull();
     }
 
     @Test
@@ -533,7 +532,7 @@
         final Drawable drawable = mock(Drawable.class);
         when(mWifiIconInjector.getIcon(anyBoolean(), anyInt())).thenReturn(drawable);
 
-        mInternetDialogController.getInternetWifiDrawable(mConnectedEntry);
+        mInternetDetailsContentController.getInternetWifiDrawable(mConnectedEntry);
 
         verify(mWifiIconInjector).getIcon(eq(false), anyInt());
         verify(drawable).setTint(mContext.getColor(R.color.connected_network_primary_color));
@@ -543,7 +542,7 @@
     public void getWifiDrawable_withWifiLevelUnreachable_returnNull() {
         when(mConnectedEntry.getLevel()).thenReturn(WIFI_LEVEL_UNREACHABLE);
 
-        assertThat(mInternetDialogController.getWifiDrawable(mConnectedEntry)).isNull();
+        assertThat(mInternetDetailsContentController.getWifiDrawable(mConnectedEntry)).isNull();
     }
 
     @Test
@@ -553,19 +552,21 @@
         Drawable hotspotDrawable = mock(Drawable.class);
         mTestableResources.addOverride(getHotspotIconResource(DEVICE_TYPE_PHONE), hotspotDrawable);
 
-        assertThat(mInternetDialogController.getWifiDrawable(entry)).isEqualTo(hotspotDrawable);
+        assertThat(mInternetDetailsContentController.getWifiDrawable(entry)).isEqualTo(
+                hotspotDrawable);
     }
 
     @Test
     public void startActivityForDialog_always_startActivityWithoutDismissShade() {
-        mInternetDialogController.startActivityForDialog(mock(Intent.class));
+        mInternetDetailsContentController.startActivityForDialog(mock(Intent.class));
 
         verify(mActivityStarter).startActivity(any(Intent.class), eq(false) /* dismissShade */);
     }
 
     @Test
     public void launchWifiDetailsSetting_withNoWifiEntryKey_doNothing() {
-        mInternetDialogController.launchWifiDetailsSetting(null /* key */, mDialogLaunchView);
+        mInternetDetailsContentController.launchWifiDetailsSetting(null /* key */,
+                mDialogLaunchView);
 
         verify(mActivityStarter, never())
                 .postStartActivityDismissingKeyguard(any(Intent.class), anyInt());
@@ -573,7 +574,8 @@
 
     @Test
     public void launchWifiDetailsSetting_withWifiEntryKey_startActivity() {
-        mInternetDialogController.launchWifiDetailsSetting("wifi_entry_key", mDialogLaunchView);
+        mInternetDetailsContentController.launchWifiDetailsSetting("wifi_entry_key",
+                mDialogLaunchView);
 
         verify(mActivityStarter).postStartActivityDismissingKeyguard(any(Intent.class), anyInt(),
                 any());
@@ -583,22 +585,22 @@
     public void isDeviceLocked_keyguardIsUnlocked_returnFalse() {
         when(mKeyguardStateController.isUnlocked()).thenReturn(true);
 
-        assertThat(mInternetDialogController.isDeviceLocked()).isFalse();
+        assertThat(mInternetDetailsContentController.isDeviceLocked()).isFalse();
     }
 
     @Test
     public void isDeviceLocked_keyguardIsLocked_returnTrue() {
         when(mKeyguardStateController.isUnlocked()).thenReturn(false);
 
-        assertThat(mInternetDialogController.isDeviceLocked()).isTrue();
+        assertThat(mInternetDetailsContentController.isDeviceLocked()).isTrue();
     }
 
     @Test
     public void onAccessPointsChanged_canNotConfigWifi_doNothing() {
         reset(mInternetDialogCallback);
-        mInternetDialogController.mCanConfigWifi = false;
+        mInternetDetailsContentController.mCanConfigWifi = false;
 
-        mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
+        mInternetDetailsContentController.onAccessPointsChanged(null /* accessPoints */);
 
         verify(mInternetDialogCallback, never()).onAccessPointsChanged(any(), any(), anyBoolean());
     }
@@ -607,7 +609,7 @@
     public void onAccessPointsChanged_nullAccessPoints_callbackBothNull() {
         reset(mInternetDialogCallback);
 
-        mInternetDialogController.onAccessPointsChanged(null /* accessPoints */);
+        mInternetDetailsContentController.onAccessPointsChanged(null /* accessPoints */);
 
         verify(mInternetDialogCallback).onAccessPointsChanged(null /* wifiEntries */,
                 null /* connectedEntry */, false /* hasMoreEntry */);
@@ -619,7 +621,7 @@
         mAccessPoints.clear();
         mAccessPoints.add(mConnectedEntry);
 
-        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+        mInternetDetailsContentController.onAccessPointsChanged(mAccessPoints);
 
         mWifiEntries.clear();
         verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries, mConnectedEntry,
@@ -632,7 +634,7 @@
         mAccessPoints.clear();
         mAccessPoints.add(mWifiEntry1);
 
-        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+        mInternetDetailsContentController.onAccessPointsChanged(mAccessPoints);
 
         mWifiEntries.clear();
         mWifiEntries.add(mWifiEntry1);
@@ -647,7 +649,7 @@
         mAccessPoints.add(mConnectedEntry);
         mAccessPoints.add(mWifiEntry1);
 
-        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+        mInternetDetailsContentController.onAccessPointsChanged(mAccessPoints);
 
         mWifiEntries.clear();
         mWifiEntries.add(mWifiEntry1);
@@ -663,7 +665,7 @@
         mAccessPoints.add(mWifiEntry1);
         mAccessPoints.add(mWifiEntry2);
 
-        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+        mInternetDetailsContentController.onAccessPointsChanged(mAccessPoints);
 
         mWifiEntries.clear();
         mWifiEntries.add(mWifiEntry1);
@@ -681,7 +683,7 @@
         mAccessPoints.add(mWifiEntry2);
         mAccessPoints.add(mWifiEntry3);
 
-        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+        mInternetDetailsContentController.onAccessPointsChanged(mAccessPoints);
 
         mWifiEntries.clear();
         mWifiEntries.add(mWifiEntry1);
@@ -699,7 +701,7 @@
         mAccessPoints.add(mWifiEntry3);
         mAccessPoints.add(mWifiEntry4);
 
-        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+        mInternetDetailsContentController.onAccessPointsChanged(mAccessPoints);
 
         mWifiEntries.clear();
         mWifiEntries.add(mWifiEntry1);
@@ -718,7 +720,7 @@
         when(mWifiEntry1.hasInternetAccess()).thenReturn(false);
         mAccessPoints.add(mWifiEntry1);
 
-        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+        mInternetDetailsContentController.onAccessPointsChanged(mAccessPoints);
 
         mWifiEntries.clear();
         mWifiEntries.add(mWifiEntry1);
@@ -735,9 +737,10 @@
         when(mWifiEntry1.hasInternetAccess()).thenReturn(false);
         mAccessPoints.add(mWifiEntry1);
 
-        mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+        mInternetDetailsContentController.onAccessPointsChanged(mAccessPoints);
 
-        verify(mWifiEntry1).setListener(mInternetDialogController.mConnectedWifiInternetMonitor);
+        verify(mWifiEntry1).setListener(
+                mInternetDetailsContentController.mConnectedWifiInternetMonitor);
     }
 
     @Test
@@ -746,8 +749,9 @@
         when(mWifiEntry1.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED);
         when(mWifiEntry1.isDefaultNetwork()).thenReturn(true);
         when(mWifiEntry1.hasInternetAccess()).thenReturn(false);
-        InternetDialogController.ConnectedWifiInternetMonitor mConnectedWifiInternetMonitor =
-                mInternetDialogController.mConnectedWifiInternetMonitor;
+        InternetDetailsContentController.ConnectedWifiInternetMonitor
+                mConnectedWifiInternetMonitor =
+                mInternetDetailsContentController.mConnectedWifiInternetMonitor;
         mConnectedWifiInternetMonitor.registerCallbackIfNeed(mWifiEntry1);
 
         // When the hasInternetAccess() changed to true, and call back the onUpdated() function.
@@ -762,7 +766,7 @@
         reset(mInternetDialogCallback);
         when(mWifiStateWorker.isWifiEnabled()).thenReturn(false);
 
-        mInternetDialogController.onWifiScan(true);
+        mInternetDetailsContentController.onWifiScan(true);
 
         verify(mInternetDialogCallback).onWifiScan(false);
     }
@@ -772,7 +776,7 @@
         reset(mInternetDialogCallback);
         when(mKeyguardStateController.isUnlocked()).thenReturn(false);
 
-        mInternetDialogController.onWifiScan(true);
+        mInternetDetailsContentController.onWifiScan(true);
 
         verify(mInternetDialogCallback).onWifiScan(false);
     }
@@ -781,7 +785,7 @@
     public void onWifiScan_onWifiScanFalse_callbackOnWifiScanFalse() {
         reset(mInternetDialogCallback);
 
-        mInternetDialogController.onWifiScan(false);
+        mInternetDetailsContentController.onWifiScan(false);
 
         verify(mInternetDialogCallback).onWifiScan(false);
     }
@@ -790,7 +794,7 @@
     public void onWifiScan_onWifiScanTrue_callbackOnWifiScanTrue() {
         reset(mInternetDialogCallback);
 
-        mInternetDialogController.onWifiScan(true);
+        mInternetDetailsContentController.onWifiScan(true);
 
         verify(mInternetDialogCallback).onWifiScan(true);
     }
@@ -800,7 +804,7 @@
         when(mCarrierConfigTracker.getCarrierProvisionsWifiMergedNetworksBool(SUB_ID))
                 .thenReturn(true);
 
-        mInternetDialogController.setMergedCarrierWifiEnabledIfNeed(SUB_ID, true);
+        mInternetDetailsContentController.setMergedCarrierWifiEnabledIfNeed(SUB_ID, true);
 
         verify(mMergedCarrierEntry, never()).setEnabled(anyBoolean());
     }
@@ -811,7 +815,7 @@
                 .thenReturn(false);
         when(mAccessPointController.getMergedCarrierEntry()).thenReturn(null);
 
-        mInternetDialogController.setMergedCarrierWifiEnabledIfNeed(SUB_ID, true);
+        mInternetDetailsContentController.setMergedCarrierWifiEnabledIfNeed(SUB_ID, true);
     }
 
     @Test
@@ -819,11 +823,11 @@
         when(mCarrierConfigTracker.getCarrierProvisionsWifiMergedNetworksBool(SUB_ID))
                 .thenReturn(false);
 
-        mInternetDialogController.setMergedCarrierWifiEnabledIfNeed(SUB_ID, true);
+        mInternetDetailsContentController.setMergedCarrierWifiEnabledIfNeed(SUB_ID, true);
 
         verify(mMergedCarrierEntry).setEnabled(true);
 
-        mInternetDialogController.setMergedCarrierWifiEnabledIfNeed(SUB_ID, false);
+        mInternetDetailsContentController.setMergedCarrierWifiEnabledIfNeed(SUB_ID, false);
 
         verify(mMergedCarrierEntry).setEnabled(false);
     }
@@ -833,11 +837,11 @@
         when(mLocationController.isLocationEnabled()).thenReturn(false);
         when(mWifiManager.isScanAlwaysAvailable()).thenReturn(false);
 
-        assertThat(mInternetDialogController.isWifiScanEnabled()).isFalse();
+        assertThat(mInternetDetailsContentController.isWifiScanEnabled()).isFalse();
 
         when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true);
 
-        assertThat(mInternetDialogController.isWifiScanEnabled()).isFalse();
+        assertThat(mInternetDetailsContentController.isWifiScanEnabled()).isFalse();
     }
 
     @Test
@@ -845,17 +849,17 @@
         when(mLocationController.isLocationEnabled()).thenReturn(true);
         when(mWifiManager.isScanAlwaysAvailable()).thenReturn(false);
 
-        assertThat(mInternetDialogController.isWifiScanEnabled()).isFalse();
+        assertThat(mInternetDetailsContentController.isWifiScanEnabled()).isFalse();
 
         when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true);
 
-        assertThat(mInternetDialogController.isWifiScanEnabled()).isTrue();
+        assertThat(mInternetDetailsContentController.isWifiScanEnabled()).isTrue();
     }
 
     @Test
     public void getSignalStrengthIcon_differentSubId() {
         mFlags.set(Flags.QS_SECONDARY_DATA_SUB_INFO, true);
-        InternetDialogController spyController = spy(mInternetDialogController);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
         Drawable icons = spyController.getSignalStrengthIcon(SUB_ID, mContext, 1, 1, 0, false);
         Drawable icons2 = spyController.getSignalStrengthIcon(SUB_ID2, mContext, 1, 1, 0, false);
 
@@ -870,12 +874,12 @@
         doReturn(SUB_ID2).when(info).getSubscriptionId();
         when(mSubscriptionManager.getActiveSubscriptionInfo(anyInt())).thenReturn(info);
 
-        int subId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
+        int subId = mInternetDetailsContentController.getActiveAutoSwitchNonDdsSubId();
         assertThat(subId).isEqualTo(SUB_ID2);
 
         // active on CBRS
         doReturn(true).when(info).isOpportunistic();
-        subId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
+        subId = mInternetDetailsContentController.getActiveAutoSwitchNonDdsSubId();
         assertThat(subId).isEqualTo(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
 
         // active on DDS
@@ -883,7 +887,7 @@
         doReturn(SUB_ID).when(info).getSubscriptionId();
         when(mSubscriptionManager.getActiveSubscriptionInfo(anyInt())).thenReturn(info);
 
-        subId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
+        subId = mInternetDetailsContentController.getActiveAutoSwitchNonDdsSubId();
         assertThat(subId).isEqualTo(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
     }
 
@@ -894,7 +898,7 @@
         doReturn(SUB_ID2).when(info).getSubscriptionId();
         when(mSubscriptionManager.getActiveSubscriptionInfo(anyInt())).thenReturn(info);
 
-        int subId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
+        int subId = mInternetDetailsContentController.getActiveAutoSwitchNonDdsSubId();
         assertThat(subId).isEqualTo(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
     }
 
@@ -908,22 +912,24 @@
         doReturn(false).when(info).isOpportunistic();
         when(mSubscriptionManager.getActiveSubscriptionInfo(anyInt())).thenReturn(info);
 
-        mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
+        mInternetDetailsContentController.getActiveAutoSwitchNonDdsSubId();
 
         // 1st time is onStart(), 2nd time is getActiveAutoSwitchNonDdsSubId()
         verify(mTelephonyManager, times(2)).registerTelephonyCallback(any(), any());
-        assertThat(mInternetDialogController.mSubIdTelephonyCallbackMap.size()).isEqualTo(2);
+        assertThat(mInternetDetailsContentController.mSubIdTelephonyCallbackMap.size()).isEqualTo(
+                2);
 
         // Adds non DDS subId again
         doReturn(SUB_ID2).when(info).getSubscriptionId();
         doReturn(false).when(info).isOpportunistic();
         when(mSubscriptionManager.getActiveSubscriptionInfo(anyInt())).thenReturn(info);
 
-        mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
+        mInternetDetailsContentController.getActiveAutoSwitchNonDdsSubId();
 
         // Does not add due to cached subInfo in mSubIdTelephonyCallbackMap.
         verify(mTelephonyManager, times(2)).registerTelephonyCallback(any(), any());
-        assertThat(mInternetDialogController.mSubIdTelephonyCallbackMap.size()).isEqualTo(2);
+        assertThat(mInternetDetailsContentController.mSubIdTelephonyCallbackMap.size()).isEqualTo(
+                2);
     }
 
     @Test
@@ -936,7 +942,7 @@
         when(SubscriptionManager.getResourcesForSubId(any(), eq(SUB_ID))).thenReturn(res1);
         when(SubscriptionManager.getResourcesForSubId(any(), eq(SUB_ID2))).thenReturn(res2);
 
-        InternetDialogController spyController = spy(mInternetDialogController);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
         Map<Integer, TelephonyDisplayInfo> mSubIdTelephonyDisplayInfoMap =
                 spyController.mSubIdTelephonyDisplayInfoMap;
         TelephonyDisplayInfo info1 = new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_EDGE,
@@ -961,7 +967,7 @@
 
     @Test
     public void getMobileNetworkSummary_flagOff() {
-        InternetDialogController spyController = spy(mInternetDialogController);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
         doReturn(true).when(spyController).isMobileDataEnabled();
         doReturn(true).when(spyController).activeNetworkIsCellular();
         String dds = spyController.getMobileNetworkSummary(SUB_ID);
@@ -972,7 +978,7 @@
     @Test
     public void launchMobileNetworkSettings_validSubId() {
         mFlags.set(Flags.QS_SECONDARY_DATA_SUB_INFO, true);
-        InternetDialogController spyController = spy(mInternetDialogController);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
         doReturn(SUB_ID2).when(spyController).getActiveAutoSwitchNonDdsSubId();
         spyController.launchMobileNetworkSettings(mDialogLaunchView);
 
@@ -983,7 +989,7 @@
     @Test
     public void launchMobileNetworkSettings_invalidSubId() {
         mFlags.set(Flags.QS_SECONDARY_DATA_SUB_INFO, true);
-        InternetDialogController spyController = spy(mInternetDialogController);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
         doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
                 .when(spyController).getActiveAutoSwitchNonDdsSubId();
         spyController.launchMobileNetworkSettings(mDialogLaunchView);
@@ -995,7 +1001,7 @@
     @Test
     public void setAutoDataSwitchMobileDataPolicy() {
         mFlags.set(Flags.QS_SECONDARY_DATA_SUB_INFO, true);
-        mInternetDialogController.setAutoDataSwitchMobileDataPolicy(SUB_ID, true);
+        mInternetDetailsContentController.setAutoDataSwitchMobileDataPolicy(SUB_ID, true);
 
         verify(mTelephonyManager).setMobileDataPolicyEnabled(eq(
                 TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH), eq(true));
@@ -1006,9 +1012,9 @@
         // Fake mobile data level as SIGNAL_STRENGTH_POOR(1)
         when(mSignalStrength.getLevel()).thenReturn(SIGNAL_STRENGTH_POOR);
         // Fake carrier network level as WIFI_LEVEL_MAX(4)
-        when(mInternetDialogController.getCarrierNetworkLevel()).thenReturn(WIFI_LEVEL_MAX);
+        when(mInternetDetailsContentController.getCarrierNetworkLevel()).thenReturn(WIFI_LEVEL_MAX);
 
-        InternetDialogController spyController = spy(mInternetDialogController);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
         spyController.getSignalStrengthDrawableWithLevel(false /* isCarrierNetworkActive */, 0);
 
         verify(spyController).getSignalStrengthIcon(eq(0), any(), eq(SIGNAL_STRENGTH_POOR),
@@ -1020,9 +1026,9 @@
         // Fake mobile data level as SIGNAL_STRENGTH_POOR(1)
         when(mSignalStrength.getLevel()).thenReturn(SIGNAL_STRENGTH_POOR);
         // Fake carrier network level as WIFI_LEVEL_MAX(4)
-        when(mInternetDialogController.getCarrierNetworkLevel()).thenReturn(WIFI_LEVEL_MAX);
+        when(mInternetDetailsContentController.getCarrierNetworkLevel()).thenReturn(WIFI_LEVEL_MAX);
 
-        InternetDialogController spyController = spy(mInternetDialogController);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
         spyController.getSignalStrengthDrawableWithLevel(true /* isCarrierNetworkActive */, 0);
 
         verify(spyController).getSignalStrengthIcon(eq(0), any(), eq(WIFI_LEVEL_MAX),
@@ -1033,14 +1039,16 @@
     public void getCarrierNetworkLevel_mergedCarrierEntryIsNull_returnMinLevel() {
         when(mAccessPointController.getMergedCarrierEntry()).thenReturn(null);
 
-        assertThat(mInternetDialogController.getCarrierNetworkLevel()).isEqualTo(WIFI_LEVEL_MIN);
+        assertThat(mInternetDetailsContentController.getCarrierNetworkLevel()).isEqualTo(
+                WIFI_LEVEL_MIN);
     }
 
     @Test
     public void getCarrierNetworkLevel_getUnreachableLevel_returnMinLevel() {
         when(mMergedCarrierEntry.getLevel()).thenReturn(WIFI_LEVEL_UNREACHABLE);
 
-        assertThat(mInternetDialogController.getCarrierNetworkLevel()).isEqualTo(WIFI_LEVEL_MIN);
+        assertThat(mInternetDetailsContentController.getCarrierNetworkLevel()).isEqualTo(
+                WIFI_LEVEL_MIN);
     }
 
     @Test
@@ -1048,7 +1056,7 @@
         for (int level = WIFI_LEVEL_MIN; level <= WIFI_LEVEL_MAX; level++) {
             when(mMergedCarrierEntry.getLevel()).thenReturn(level);
 
-            assertThat(mInternetDialogController.getCarrierNetworkLevel()).isEqualTo(level);
+            assertThat(mInternetDetailsContentController.getCarrierNetworkLevel()).isEqualTo(level);
         }
     }
 
@@ -1057,7 +1065,7 @@
         Resources res = mock(Resources.class);
         doReturn("Carrier network changing").when(res).getString(anyInt());
         when(SubscriptionManager.getResourcesForSubId(any(), eq(SUB_ID))).thenReturn(res);
-        InternetDialogController spyController = spy(mInternetDialogController);
+        InternetDetailsContentController spyController = spy(mInternetDetailsContentController);
         Map<Integer, TelephonyDisplayInfo> mSubIdTelephonyDisplayInfoMap =
                 spyController.mSubIdTelephonyDisplayInfoMap;
         TelephonyDisplayInfo info = new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
@@ -1076,14 +1084,14 @@
     public void getConfiguratorQrCodeGeneratorIntentOrNull_wifiNotShareable_returnNull() {
         mFlags.set(Flags.SHARE_WIFI_QS_BUTTON, true);
         when(mConnectedEntry.canShare()).thenReturn(false);
-        assertThat(mInternetDialogController.getConfiguratorQrCodeGeneratorIntentOrNull(
+        assertThat(mInternetDetailsContentController.getConfiguratorQrCodeGeneratorIntentOrNull(
                 mConnectedEntry)).isNull();
     }
     @Test
     public void getConfiguratorQrCodeGeneratorIntentOrNull_flagOff_returnNull() {
         mFlags.set(Flags.SHARE_WIFI_QS_BUTTON, false);
         when(mConnectedEntry.canShare()).thenReturn(true);
-        assertThat(mInternetDialogController.getConfiguratorQrCodeGeneratorIntentOrNull(
+        assertThat(mInternetDetailsContentController.getConfiguratorQrCodeGeneratorIntentOrNull(
                 mConnectedEntry)).isNull();
     }
 
@@ -1092,7 +1100,7 @@
         mFlags.set(Flags.SHARE_WIFI_QS_BUTTON, true);
         when(mConnectedEntry.canShare()).thenReturn(true);
         when(mConnectedEntry.getWifiConfiguration()).thenReturn(null);
-        assertThat(mInternetDialogController.getConfiguratorQrCodeGeneratorIntentOrNull(
+        assertThat(mInternetDetailsContentController.getConfiguratorQrCodeGeneratorIntentOrNull(
                 mConnectedEntry)).isNull();
     }
 
@@ -1101,30 +1109,34 @@
         mFlags.set(Flags.SHARE_WIFI_QS_BUTTON, true);
         when(mConnectedEntry.canShare()).thenReturn(true);
         when(mConnectedEntry.getWifiConfiguration()).thenReturn(mWifiConfiguration);
-        assertThat(mInternetDialogController.getConfiguratorQrCodeGeneratorIntentOrNull(
+        assertThat(mInternetDetailsContentController.getConfiguratorQrCodeGeneratorIntentOrNull(
                 mConnectedEntry)).isNotNull();
     }
 
     @Test
     public void onStop_cleanUp() {
         doReturn(SUB_ID).when(mTelephonyManager).getSubscriptionId();
-        assertThat(mInternetDialogController.mSubIdTelephonyManagerMap.get(SUB_ID)).isEqualTo(
+        assertThat(
+                mInternetDetailsContentController.mSubIdTelephonyManagerMap.get(SUB_ID)).isEqualTo(
                 mTelephonyManager);
-        assertThat(mInternetDialogController.mSubIdTelephonyCallbackMap.get(SUB_ID)).isNotNull();
-        assertThat(mInternetDialogController.mCallback).isNotNull();
+        assertThat(mInternetDetailsContentController.mSubIdTelephonyCallbackMap.get(
+                SUB_ID)).isNotNull();
+        assertThat(mInternetDetailsContentController.mCallback).isNotNull();
 
-        mInternetDialogController.onStop();
+        mInternetDetailsContentController.onStop();
 
         verify(mTelephonyManager).unregisterTelephonyCallback(any(TelephonyCallback.class));
-        assertThat(mInternetDialogController.mSubIdTelephonyDisplayInfoMap.isEmpty()).isTrue();
-        assertThat(mInternetDialogController.mSubIdTelephonyManagerMap.isEmpty()).isTrue();
-        assertThat(mInternetDialogController.mSubIdTelephonyCallbackMap.isEmpty()).isTrue();
-        verify(mSubscriptionManager).removeOnSubscriptionsChangedListener(mInternetDialogController
-                .mOnSubscriptionsChangedListener);
-        verify(mAccessPointController).removeAccessPointCallback(mInternetDialogController);
+        assertThat(
+                mInternetDetailsContentController.mSubIdTelephonyDisplayInfoMap.isEmpty()).isTrue();
+        assertThat(mInternetDetailsContentController.mSubIdTelephonyManagerMap.isEmpty()).isTrue();
+        assertThat(mInternetDetailsContentController.mSubIdTelephonyCallbackMap.isEmpty()).isTrue();
+        verify(mSubscriptionManager).removeOnSubscriptionsChangedListener(
+                mInternetDetailsContentController
+                        .mOnSubscriptionsChangedListener);
+        verify(mAccessPointController).removeAccessPointCallback(mInternetDetailsContentController);
         verify(mConnectivityManager).unregisterNetworkCallback(
                 any(ConnectivityManager.NetworkCallback.class));
-        assertThat(mInternetDialogController.mCallback).isNull();
+        assertThat(mInternetDetailsContentController.mCallback).isNull();
     }
 
     @Test
@@ -1132,16 +1144,16 @@
         when(SubscriptionManager.getDefaultDataSubscriptionId())
                 .thenReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
 
-        mInternetDialogController.mOnSubscriptionsChangedListener.onSubscriptionsChanged();
+        mInternetDetailsContentController.mOnSubscriptionsChangedListener.onSubscriptionsChanged();
 
-        assertThat(mInternetDialogController.hasActiveSubIdOnDds()).isFalse();
+        assertThat(mInternetDetailsContentController.hasActiveSubIdOnDds()).isFalse();
     }
 
     @Test
     public void hasActiveSubIdOnDds_activeDds_returnTrue() {
-        mInternetDialogController.mOnSubscriptionsChangedListener.onSubscriptionsChanged();
+        mInternetDetailsContentController.mOnSubscriptionsChangedListener.onSubscriptionsChanged();
 
-        assertThat(mInternetDialogController.hasActiveSubIdOnDds()).isTrue();
+        assertThat(mInternetDetailsContentController.hasActiveSubIdOnDds()).isTrue();
     }
 
     @Test
@@ -1153,9 +1165,9 @@
         when(info.getProfileClass()).thenReturn(PROFILE_CLASS_PROVISIONING);
         when(mSubscriptionManager.getActiveSubscriptionInfo(SUB_ID)).thenReturn(info);
 
-        mInternetDialogController.mOnSubscriptionsChangedListener.onSubscriptionsChanged();
+        mInternetDetailsContentController.mOnSubscriptionsChangedListener.onSubscriptionsChanged();
 
-        assertThat(mInternetDialogController.hasActiveSubIdOnDds()).isFalse();
+        assertThat(mInternetDetailsContentController.hasActiveSubIdOnDds()).isFalse();
     }
 
     @Test
@@ -1167,9 +1179,9 @@
         when(info.isOnlyNonTerrestrialNetwork()).thenReturn(true);
         when(mSubscriptionManager.getActiveSubscriptionInfo(SUB_ID)).thenReturn(info);
 
-        mInternetDialogController.mOnSubscriptionsChangedListener.onSubscriptionsChanged();
+        mInternetDetailsContentController.mOnSubscriptionsChangedListener.onSubscriptionsChanged();
 
-        assertFalse(mInternetDialogController.hasActiveSubIdOnDds());
+        assertFalse(mInternetDetailsContentController.hasActiveSubIdOnDds());
     }
 
     @Test
@@ -1181,9 +1193,9 @@
         when(info.isOnlyNonTerrestrialNetwork()).thenReturn(false);
         when(mSubscriptionManager.getActiveSubscriptionInfo(SUB_ID)).thenReturn(info);
 
-        mInternetDialogController.mOnSubscriptionsChangedListener.onSubscriptionsChanged();
+        mInternetDetailsContentController.mOnSubscriptionsChangedListener.onSubscriptionsChanged();
 
-        assertTrue(mInternetDialogController.hasActiveSubIdOnDds());
+        assertTrue(mInternetDetailsContentController.hasActiveSubIdOnDds());
     }
 
     private String getResourcesString(String name) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateLegacyTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateLegacyTest.java
new file mode 100644
index 0000000..2385515
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateLegacyTest.java
@@ -0,0 +1,841 @@
+package com.android.systemui.qs.tiles.dialog;
+
+import static com.android.systemui.qs.tiles.dialog.InternetDetailsContentController.MAX_WIFI_ENTRY_COUNT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.os.Handler;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.testing.TestableLooper;
+import android.view.View;
+import android.view.Window;
+import android.widget.LinearLayout;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.internal.logging.UiEventLogger;
+import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.animation.DialogTransitionAnimator;
+import com.android.systemui.res.R;
+import com.android.systemui.shade.domain.interactor.FakeShadeDialogContextInteractor;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
+import com.android.wifitrackerlib.WifiEntry;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
+
+import java.util.List;
+
+import kotlinx.coroutines.CoroutineScope;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@UiThreadTest
+public class InternetDialogDelegateLegacyTest extends SysuiTestCase {
+
+    private static final String MOBILE_NETWORK_TITLE = "Mobile Title";
+    private static final String MOBILE_NETWORK_SUMMARY = "Mobile Summary";
+    private static final String WIFI_TITLE = "Connected Wi-Fi Title";
+    private static final String WIFI_SUMMARY = "Connected Wi-Fi Summary";
+
+    @Mock
+    private Handler mHandler;
+    @Mock
+    CoroutineScope mScope;
+    @Mock
+    private TelephonyManager mTelephonyManager;
+    @Mock
+    private WifiEntry mInternetWifiEntry;
+    @Mock
+    private List<WifiEntry> mWifiEntries;
+    @Mock
+    private InternetAdapter mInternetAdapter;
+    @Mock
+    private InternetDetailsContentController mInternetDetailsContentController;
+    @Mock
+    private KeyguardStateController mKeyguard;
+    @Mock
+    private DialogTransitionAnimator mDialogTransitionAnimator;
+    @Mock
+    private SystemUIDialog.Factory mSystemUIDialogFactory;
+    @Mock
+    private SystemUIDialog mSystemUIDialog;
+    @Mock
+    private Window mWindow;
+
+    private FakeExecutor mBgExecutor = new FakeExecutor(new FakeSystemClock());
+    private InternetDialogDelegateLegacy mInternetDialogDelegateLegacy;
+    private View mDialogView;
+    private View mSubTitle;
+    private LinearLayout mEthernet;
+    private LinearLayout mMobileDataLayout;
+    private Switch mMobileToggleSwitch;
+    private LinearLayout mWifiToggle;
+    private Switch mWifiToggleSwitch;
+    private TextView mWifiToggleSummary;
+    private LinearLayout mConnectedWifi;
+    private RecyclerView mWifiList;
+    private LinearLayout mSeeAll;
+    private LinearLayout mWifiScanNotify;
+    private TextView mAirplaneModeSummaryText;
+
+    private MockitoSession mMockitoSession;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt());
+        when(mInternetWifiEntry.getTitle()).thenReturn(WIFI_TITLE);
+        when(mInternetWifiEntry.getSummary(false)).thenReturn(WIFI_SUMMARY);
+        when(mInternetWifiEntry.isDefaultNetwork()).thenReturn(true);
+        when(mInternetWifiEntry.hasInternetAccess()).thenReturn(true);
+        when(mWifiEntries.size()).thenReturn(1);
+
+        when(mInternetDetailsContentController.getMobileNetworkTitle(anyInt()))
+                .thenReturn(MOBILE_NETWORK_TITLE);
+        when(mInternetDetailsContentController.getMobileNetworkSummary(anyInt()))
+                .thenReturn(MOBILE_NETWORK_SUMMARY);
+        when(mInternetDetailsContentController.isWifiEnabled()).thenReturn(true);
+        when(mInternetDetailsContentController.getActiveAutoSwitchNonDdsSubId()).thenReturn(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        mMockitoSession = ExtendedMockito.mockitoSession()
+                .spyStatic(WifiEnterpriseRestrictionUtils.class)
+                .startMocking();
+        when(WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(mContext)).thenReturn(true);
+        when(mSystemUIDialogFactory.create(any(SystemUIDialog.Delegate.class), eq(mContext)))
+                .thenReturn(mSystemUIDialog);
+        when(mSystemUIDialog.getContext()).thenReturn(mContext);
+        when(mSystemUIDialog.getWindow()).thenReturn(mWindow);
+        createInternetDialog();
+    }
+
+    private void createInternetDialog() {
+        mInternetDialogDelegateLegacy = new InternetDialogDelegateLegacy(
+                mContext,
+                mock(InternetDialogManager.class),
+                mInternetDetailsContentController,
+                true,
+                true,
+                true,
+                mScope,
+                mock(UiEventLogger.class),
+                mDialogTransitionAnimator,
+                mHandler,
+                mBgExecutor,
+                mKeyguard,
+                mSystemUIDialogFactory,
+                new FakeShadeDialogContextInteractor(mContext));
+        mInternetDialogDelegateLegacy.createDialog();
+        mInternetDialogDelegateLegacy.onCreate(mSystemUIDialog, null);
+        mInternetDialogDelegateLegacy.mAdapter = mInternetAdapter;
+        mInternetDialogDelegateLegacy.mConnectedWifiEntry = mInternetWifiEntry;
+        mInternetDialogDelegateLegacy.mWifiEntriesCount = mWifiEntries.size();
+
+        mDialogView = mInternetDialogDelegateLegacy.mDialogView;
+        mSubTitle = mDialogView.requireViewById(R.id.internet_dialog_subtitle);
+        mEthernet = mDialogView.requireViewById(R.id.ethernet_layout);
+        mMobileDataLayout = mDialogView.requireViewById(R.id.mobile_network_layout);
+        mMobileToggleSwitch = mDialogView.requireViewById(R.id.mobile_toggle);
+        mWifiToggle = mDialogView.requireViewById(R.id.turn_on_wifi_layout);
+        mWifiToggleSwitch = mDialogView.requireViewById(R.id.wifi_toggle);
+        mWifiToggleSummary = mDialogView.requireViewById(R.id.wifi_toggle_summary);
+        mConnectedWifi = mDialogView.requireViewById(R.id.wifi_connected_layout);
+        mWifiList = mDialogView.requireViewById(R.id.wifi_list_layout);
+        mSeeAll = mDialogView.requireViewById(R.id.see_all_layout);
+        mWifiScanNotify = mDialogView.requireViewById(R.id.wifi_scan_notify_layout);
+        mAirplaneModeSummaryText = mDialogView.requireViewById(R.id.airplane_mode_summary);
+        mInternetDialogDelegateLegacy.onStart(mSystemUIDialog);
+    }
+
+    @After
+    public void tearDown() {
+        mInternetDialogDelegateLegacy.onStop(mSystemUIDialog);
+        mInternetDialogDelegateLegacy.dismissDialog();
+        mMockitoSession.finishMocking();
+    }
+
+    @Test
+    public void createInternetDialog_setAccessibilityPaneTitleToQuickSettings() {
+        assertThat(mDialogView.getAccessibilityPaneTitle())
+                .isEqualTo(mContext.getText(R.string.accessibility_desc_quick_settings));
+    }
+
+    @Test
+    public void hideWifiViews_WifiViewsGone() {
+        mInternetDialogDelegateLegacy.hideWifiViews();
+
+        assertThat(mInternetDialogDelegateLegacy.mIsProgressBarVisible).isFalse();
+        assertThat(mWifiToggle.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mWifiList.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mSeeAll.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void updateDialog_withApmOn_internetDialogSubTitleGone() {
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(true);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mSubTitle.getVisibility()).isEqualTo(View.VISIBLE);
+                });
+    }
+
+    @Test
+    public void updateDialog_withApmOff_internetDialogSubTitleVisible() {
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(false);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mSubTitle.getVisibility()).isEqualTo(View.VISIBLE);
+                });
+    }
+
+    @Test
+    public void updateDialog_apmOffAndHasEthernet_showEthernet() {
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(false);
+        when(mInternetDetailsContentController.hasEthernet()).thenReturn(true);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mEthernet.getVisibility()).isEqualTo(View.VISIBLE);
+                });
+    }
+
+    @Test
+    public void updateDialog_apmOffAndNoEthernet_hideEthernet() {
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(false);
+        when(mInternetDetailsContentController.hasEthernet()).thenReturn(false);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mEthernet.getVisibility()).isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_apmOnAndHasEthernet_showEthernet() {
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(true);
+        when(mInternetDetailsContentController.hasEthernet()).thenReturn(true);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mEthernet.getVisibility()).isEqualTo(View.VISIBLE);
+                });
+    }
+
+    @Test
+    public void updateDialog_apmOnAndNoEthernet_hideEthernet() {
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(true);
+        when(mInternetDetailsContentController.hasEthernet()).thenReturn(false);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mEthernet.getVisibility()).isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_apmOffAndNotCarrierNetwork_mobileDataLayoutGone() {
+        // Mobile network should be gone if the list of active subscriptionId is null.
+        when(mInternetDetailsContentController.isCarrierNetworkActive()).thenReturn(false);
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(false);
+        when(mInternetDetailsContentController.hasActiveSubIdOnDds()).thenReturn(false);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mMobileDataLayout.getVisibility()).isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_apmOnWithCarrierNetworkAndWifiStatus_mobileDataLayoutVisible() {
+        // Carrier network should be visible if airplane mode ON and Wi-Fi is ON.
+        when(mInternetDetailsContentController.isCarrierNetworkActive()).thenReturn(true);
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(true);
+        when(mInternetDetailsContentController.isWifiEnabled()).thenReturn(true);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mMobileDataLayout.getVisibility()).isEqualTo(View.VISIBLE);
+                });
+    }
+
+    @Test
+    public void updateDialog_apmOnWithCarrierNetworkAndWifiStatus_mobileDataLayoutGone() {
+        // Carrier network should be gone if airplane mode ON and Wi-Fi is off.
+        when(mInternetDetailsContentController.isCarrierNetworkActive()).thenReturn(true);
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(true);
+        when(mInternetDetailsContentController.isWifiEnabled()).thenReturn(false);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mMobileDataLayout.getVisibility()).isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_apmOnAndNoCarrierNetwork_mobileDataLayoutGone() {
+        when(mInternetDetailsContentController.isCarrierNetworkActive()).thenReturn(false);
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(true);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mMobileDataLayout.getVisibility()).isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_apmOnAndWifiOnHasCarrierNetwork_showAirplaneSummary() {
+        when(mInternetDetailsContentController.isCarrierNetworkActive()).thenReturn(true);
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(true);
+        mInternetDialogDelegateLegacy.mConnectedWifiEntry = null;
+        doReturn(false).when(mInternetDetailsContentController).activeNetworkIsCellular();
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mMobileDataLayout.getVisibility()).isEqualTo(View.VISIBLE);
+                    assertThat(mAirplaneModeSummaryText.getVisibility()).isEqualTo(View.VISIBLE);
+                });
+    }
+
+    @Test
+    public void updateDialog_apmOffAndWifiOnHasCarrierNetwork_notShowApmSummary() {
+        when(mInternetDetailsContentController.isCarrierNetworkActive()).thenReturn(true);
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(false);
+        mInternetDialogDelegateLegacy.mConnectedWifiEntry = null;
+        doReturn(false).when(mInternetDetailsContentController).activeNetworkIsCellular();
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mAirplaneModeSummaryText.getVisibility()).isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_apmOffAndHasCarrierNetwork_notShowApmSummary() {
+        when(mInternetDetailsContentController.isCarrierNetworkActive()).thenReturn(true);
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(false);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mAirplaneModeSummaryText.getVisibility()).isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_apmOnAndNoCarrierNetwork_notShowApmSummary() {
+        when(mInternetDetailsContentController.isCarrierNetworkActive()).thenReturn(false);
+        when(mInternetDetailsContentController.isAirplaneModeEnabled()).thenReturn(true);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mAirplaneModeSummaryText.getVisibility()).isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_mobileDataIsEnabled_checkMobileDataSwitch() {
+        doReturn(true).when(mInternetDetailsContentController).hasActiveSubIdOnDds();
+        when(mInternetDetailsContentController.isCarrierNetworkActive()).thenReturn(true);
+        when(mInternetDetailsContentController.isMobileDataEnabled()).thenReturn(true);
+        mMobileToggleSwitch.setChecked(false);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mMobileToggleSwitch.isChecked()).isTrue();
+                });
+    }
+
+    @Test
+    public void updateDialog_mobileDataIsNotChanged_checkMobileDataSwitch() {
+        doReturn(true).when(mInternetDetailsContentController).hasActiveSubIdOnDds();
+        when(mInternetDetailsContentController.isCarrierNetworkActive()).thenReturn(true);
+        when(mInternetDetailsContentController.isMobileDataEnabled()).thenReturn(false);
+        mMobileToggleSwitch.setChecked(false);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mMobileToggleSwitch.isChecked()).isFalse();
+                });
+    }
+
+    @Test
+    public void updateDialog_wifiOnAndHasInternetWifi_showConnectedWifi() {
+        when(mInternetDetailsContentController.getActiveAutoSwitchNonDdsSubId()).thenReturn(1);
+        doReturn(true).when(mInternetDetailsContentController).hasActiveSubIdOnDds();
+        // The preconditions WiFi ON and Internet WiFi are already in setUp()
+        doReturn(false).when(mInternetDetailsContentController).activeNetworkIsCellular();
+
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.VISIBLE);
+                    LinearLayout secondaryLayout = mDialogView.requireViewById(
+                            R.id.secondary_mobile_network_layout);
+                    assertThat(secondaryLayout.getVisibility()).isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_wifiOnAndNoConnectedWifi_hideConnectedWifi() {
+        // The precondition WiFi ON is already in setUp()
+        mInternetDialogDelegateLegacy.mConnectedWifiEntry = null;
+        doReturn(false).when(mInternetDetailsContentController).activeNetworkIsCellular();
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_wifiOnAndNoWifiEntry_showWifiListAndSeeAllArea() {
+        // The precondition WiFi ON is already in setUp()
+        mInternetDialogDelegateLegacy.mConnectedWifiEntry = null;
+        mInternetDialogDelegateLegacy.mWifiEntriesCount = 0;
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
+                    // Show a blank block to fix the dialog height even if there is no WiFi list
+                    assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
+                    verify(mInternetAdapter).setMaxEntriesCount(3);
+                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.INVISIBLE);
+                });
+    }
+
+    @Test
+    public void updateDialog_wifiOnAndOneWifiEntry_showWifiListAndSeeAllArea() {
+        // The precondition WiFi ON is already in setUp()
+        mInternetDialogDelegateLegacy.mConnectedWifiEntry = null;
+        mInternetDialogDelegateLegacy.mWifiEntriesCount = 1;
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
+                    // Show a blank block to fix the dialog height even if there is no WiFi list
+                    assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
+                    verify(mInternetAdapter).setMaxEntriesCount(3);
+                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.INVISIBLE);
+                });
+    }
+
+    @Test
+    public void updateDialog_wifiOnAndHasConnectedWifi_showAllWifiAndSeeAllArea() {
+        // The preconditions WiFi ON and WiFi entries are already in setUp()
+        mInternetDialogDelegateLegacy.mWifiEntriesCount = 0;
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.VISIBLE);
+                    // Show a blank block to fix the dialog height even if there is no WiFi list
+                    assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
+                    verify(mInternetAdapter).setMaxEntriesCount(2);
+                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.INVISIBLE);
+                });
+    }
+
+    @Test
+    public void updateDialog_wifiOnAndHasMaxWifiList_showWifiListAndSeeAll() {
+        // The preconditions WiFi ON and WiFi entries are already in setUp()
+        mInternetDialogDelegateLegacy.mConnectedWifiEntry = null;
+        mInternetDialogDelegateLegacy.mWifiEntriesCount = MAX_WIFI_ENTRY_COUNT;
+        mInternetDialogDelegateLegacy.mHasMoreWifiEntries = true;
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
+                    assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
+                    verify(mInternetAdapter).setMaxEntriesCount(3);
+                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.VISIBLE);
+                });
+    }
+
+    @Test
+    public void updateDialog_wifiOnAndHasBothWifiEntry_showBothWifiEntryAndSeeAll() {
+        // The preconditions WiFi ON and WiFi entries are already in setUp()
+        mInternetDialogDelegateLegacy.mWifiEntriesCount = MAX_WIFI_ENTRY_COUNT - 1;
+        mInternetDialogDelegateLegacy.mHasMoreWifiEntries = true;
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.VISIBLE);
+                    assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
+                    verify(mInternetAdapter).setMaxEntriesCount(2);
+                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.VISIBLE);
+                });
+    }
+
+    @Test
+    public void updateDialog_deviceLockedAndNoConnectedWifi_showWifiToggle() {
+        // The preconditions WiFi entries are already in setUp()
+        when(mInternetDetailsContentController.isDeviceLocked()).thenReturn(true);
+        mInternetDialogDelegateLegacy.mConnectedWifiEntry = null;
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    // Show WiFi Toggle without background
+                    assertThat(mWifiToggle.getVisibility()).isEqualTo(View.VISIBLE);
+                    assertThat(mWifiToggle.getBackground()).isNull();
+                    // Hide Wi-Fi networks and See all
+                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
+                    assertThat(mWifiList.getVisibility()).isEqualTo(View.GONE);
+                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_deviceLockedAndHasConnectedWifi_showWifiToggleWithBackground() {
+        // The preconditions WiFi ON and WiFi entries are already in setUp()
+        when(mInternetDetailsContentController.isDeviceLocked()).thenReturn(true);
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    // Show WiFi Toggle with highlight background
+                    assertThat(mWifiToggle.getVisibility()).isEqualTo(View.VISIBLE);
+                    assertThat(mWifiToggle.getBackground()).isNotNull();
+                    // Hide Wi-Fi networks and See all
+                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
+                    assertThat(mWifiList.getVisibility()).isEqualTo(View.GONE);
+                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_disallowChangeWifiState_disableWifiSwitch() {
+        mInternetDialogDelegateLegacy.dismissDialog();
+        when(WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(mContext)).thenReturn(false);
+        createInternetDialog();
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    // Disable Wi-Fi switch and show restriction message in summary.
+                    assertThat(mWifiToggleSwitch.isEnabled()).isFalse();
+                    assertThat(mWifiToggleSummary.getVisibility()).isEqualTo(View.VISIBLE);
+                    assertThat(mWifiToggleSummary.getText().length()).isNotEqualTo(0);
+                });
+    }
+
+    @Test
+    public void updateDialog_allowChangeWifiState_enableWifiSwitch() {
+        mInternetDialogDelegateLegacy.dismissDialog();
+        when(WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(mContext)).thenReturn(true);
+        createInternetDialog();
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    // Enable Wi-Fi switch and hide restriction message in summary.
+                    assertThat(mWifiToggleSwitch.isEnabled()).isTrue();
+                    assertThat(mWifiToggleSummary.getVisibility()).isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_showSecondaryDataSub() {
+        when(mInternetDetailsContentController.getActiveAutoSwitchNonDdsSubId()).thenReturn(1);
+        doReturn(1).when(mInternetDetailsContentController).getActiveAutoSwitchNonDdsSubId();
+        doReturn(true).when(mInternetDetailsContentController).hasActiveSubIdOnDds();
+        doReturn(false).when(mInternetDetailsContentController).isAirplaneModeEnabled();
+        clearInvocations(mInternetDetailsContentController);
+        mInternetDialogDelegateLegacy.updateDialog(true);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    LinearLayout primaryLayout = mDialogView.requireViewById(
+                            R.id.mobile_network_layout);
+                    LinearLayout secondaryLayout = mDialogView.requireViewById(
+                            R.id.secondary_mobile_network_layout);
+
+                    verify(mInternetDetailsContentController).getMobileNetworkSummary(1);
+                    assertThat(primaryLayout.getBackground()).isNotEqualTo(
+                            secondaryLayout.getBackground());
+                });
+    }
+
+    @Test
+    public void updateDialog_wifiOn_hideWifiScanNotify() {
+        // The preconditions WiFi ON and WiFi entries are already in setUp()
+
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
+                });
+
+        assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void updateDialog_wifiOffAndWifiScanOff_hideWifiScanNotify() {
+        when(mInternetDetailsContentController.isWifiEnabled()).thenReturn(false);
+        when(mInternetDetailsContentController.isWifiScanEnabled()).thenReturn(false);
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
+                });
+
+        assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void updateDialog_wifiOffAndWifiScanOnAndDeviceLocked_hideWifiScanNotify() {
+        when(mInternetDetailsContentController.isWifiEnabled()).thenReturn(false);
+        when(mInternetDetailsContentController.isWifiScanEnabled()).thenReturn(true);
+        when(mInternetDetailsContentController.isDeviceLocked()).thenReturn(true);
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
+                });
+
+        assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void updateDialog_wifiOffAndWifiScanOnAndDeviceUnlocked_showWifiScanNotify() {
+        when(mInternetDetailsContentController.isWifiEnabled()).thenReturn(false);
+        when(mInternetDetailsContentController.isWifiScanEnabled()).thenReturn(true);
+        when(mInternetDetailsContentController.isDeviceLocked()).thenReturn(false);
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.VISIBLE);
+                    TextView wifiScanNotifyText = mDialogView.requireViewById(
+                            R.id.wifi_scan_notify_text);
+                    assertThat(wifiScanNotifyText.getText().length()).isNotEqualTo(0);
+                    assertThat(wifiScanNotifyText.getMovementMethod()).isNotNull();
+                });
+    }
+
+    @Test
+    public void updateDialog_wifiIsDisabled_uncheckWifiSwitch() {
+        when(mInternetDetailsContentController.isWifiEnabled()).thenReturn(false);
+        mWifiToggleSwitch.setChecked(true);
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mWifiToggleSwitch.isChecked()).isFalse();
+                });
+    }
+
+    @Test
+    public void updateDialog_wifiIsEnabled_checkWifiSwitch() throws Exception {
+        when(mInternetDetailsContentController.isWifiEnabled()).thenReturn(true);
+        mWifiToggleSwitch.setChecked(false);
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mWifiToggleSwitch.isChecked()).isTrue();
+                });
+    }
+
+    @Test
+    public void onClickSeeMoreButton_clickSeeAll_verifyLaunchNetworkSetting() {
+        mSeeAll.performClick();
+
+        verify(mInternetDetailsContentController).launchNetworkSetting(
+                mDialogView.requireViewById(R.id.see_all_layout));
+    }
+
+    @Test
+    public void onWifiScan_isScanTrue_setProgressBarVisibleTrue() {
+        mInternetDialogDelegateLegacy.mIsProgressBarVisible = false;
+
+        mInternetDialogDelegateLegacy.onWifiScan(true);
+
+        assertThat(mInternetDialogDelegateLegacy.mIsProgressBarVisible).isTrue();
+    }
+
+    @Test
+    public void onWifiScan_isScanFalse_setProgressBarVisibleFalse() {
+        mInternetDialogDelegateLegacy.mIsProgressBarVisible = true;
+
+        mInternetDialogDelegateLegacy.onWifiScan(false);
+
+        assertThat(mInternetDialogDelegateLegacy.mIsProgressBarVisible).isFalse();
+    }
+
+    @Test
+    public void getWifiListMaxCount_returnCountCorrectly() {
+        // Both of the Ethernet, MobileData is hidden.
+        // Then the maximum count is equal to MAX_WIFI_ENTRY_COUNT.
+        setNetworkVisible(false, false, false);
+
+        assertThat(mInternetDialogDelegateLegacy.getWifiListMaxCount()).isEqualTo(
+                MAX_WIFI_ENTRY_COUNT);
+
+        // If the Connected Wi-Fi is displayed then reduce one of the Wi-Fi list max count.
+        setNetworkVisible(false, false, true);
+
+        assertThat(mInternetDialogDelegateLegacy.getWifiListMaxCount())
+                .isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
+
+        // Only one of Ethernet, MobileData is displayed.
+        // Then the maximum count is equal to MAX_WIFI_ENTRY_COUNT.
+        setNetworkVisible(true, false, false);
+
+        assertThat(mInternetDialogDelegateLegacy.getWifiListMaxCount()).isEqualTo(
+                MAX_WIFI_ENTRY_COUNT);
+
+        setNetworkVisible(false, true, false);
+
+        assertThat(mInternetDialogDelegateLegacy.getWifiListMaxCount()).isEqualTo(
+                MAX_WIFI_ENTRY_COUNT);
+
+        // If the Connected Wi-Fi is displayed then reduce one of the Wi-Fi list max count.
+        setNetworkVisible(true, false, true);
+
+        assertThat(mInternetDialogDelegateLegacy.getWifiListMaxCount())
+                .isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
+
+        setNetworkVisible(false, true, true);
+
+        assertThat(mInternetDialogDelegateLegacy.getWifiListMaxCount())
+                .isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
+
+        // Both of Ethernet, MobileData, ConnectedWiFi is displayed.
+        // Then the maximum count is equal to MAX_WIFI_ENTRY_COUNT - 1.
+        setNetworkVisible(true, true, false);
+
+        assertThat(mInternetDialogDelegateLegacy.getWifiListMaxCount())
+                .isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
+
+        // If the Connected Wi-Fi is displayed then reduce one of the Wi-Fi list max count.
+        setNetworkVisible(true, true, true);
+
+        assertThat(mInternetDialogDelegateLegacy.getWifiListMaxCount())
+                .isEqualTo(MAX_WIFI_ENTRY_COUNT - 2);
+    }
+
+    @Test
+    public void updateDialog_shareWifiIntentNull_hideButton() {
+        when(mInternetDetailsContentController.getConfiguratorQrCodeGeneratorIntentOrNull(any()))
+                .thenReturn(null);
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(
+                            mInternetDialogDelegateLegacy.mShareWifiButton.getVisibility())
+                            .isEqualTo(View.GONE);
+                });
+    }
+
+    @Test
+    public void updateDialog_shareWifiShareable_showButton() {
+        when(mInternetDetailsContentController.getConfiguratorQrCodeGeneratorIntentOrNull(any()))
+                .thenReturn(new Intent());
+        mInternetDialogDelegateLegacy.updateDialog(false);
+        mBgExecutor.runAllReady();
+
+        mInternetDialogDelegateLegacy.mDataInternetContent.observe(
+                mInternetDialogDelegateLegacy.mLifecycleOwner, i -> {
+                    assertThat(mInternetDialogDelegateLegacy.mShareWifiButton.getVisibility())
+                            .isEqualTo(View.VISIBLE);
+                });
+    }
+
+    private void setNetworkVisible(boolean ethernetVisible, boolean mobileDataVisible,
+            boolean connectedWifiVisible) {
+        mEthernet.setVisibility(ethernetVisible ? View.VISIBLE : View.GONE);
+        mMobileDataLayout.setVisibility(mobileDataVisible ? View.VISIBLE : View.GONE);
+        mConnectedWifi.setVisibility(connectedWifiVisible ? View.VISIBLE : View.GONE);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateTest.java
deleted file mode 100644
index 8560b67..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateTest.java
+++ /dev/null
@@ -1,837 +0,0 @@
-package com.android.systemui.qs.tiles.dialog;
-
-import static com.android.systemui.qs.tiles.dialog.InternetDialogController.MAX_WIFI_ENTRY_COUNT;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Intent;
-import android.os.Handler;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.testing.TestableLooper;
-import android.view.View;
-import android.view.Window;
-import android.widget.LinearLayout;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.annotation.UiThreadTest;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.dx.mockito.inline.extended.ExtendedMockito;
-import com.android.internal.logging.UiEventLogger;
-import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.animation.DialogTransitionAnimator;
-import com.android.systemui.res.R;
-import com.android.systemui.shade.domain.interactor.FakeShadeDialogContextInteractor;
-import com.android.systemui.statusbar.phone.SystemUIDialog;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-import com.android.wifitrackerlib.WifiEntry;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.MockitoSession;
-
-import java.util.List;
-
-import kotlinx.coroutines.CoroutineScope;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-@TestableLooper.RunWithLooper(setAsMainLooper = true)
-@UiThreadTest
-public class InternetDialogDelegateTest extends SysuiTestCase {
-
-    private static final String MOBILE_NETWORK_TITLE = "Mobile Title";
-    private static final String MOBILE_NETWORK_SUMMARY = "Mobile Summary";
-    private static final String WIFI_TITLE = "Connected Wi-Fi Title";
-    private static final String WIFI_SUMMARY = "Connected Wi-Fi Summary";
-
-    @Mock
-    private Handler mHandler;
-    @Mock
-    CoroutineScope mScope;
-    @Mock
-    private TelephonyManager mTelephonyManager;
-    @Mock
-    private WifiEntry mInternetWifiEntry;
-    @Mock
-    private List<WifiEntry> mWifiEntries;
-    @Mock
-    private InternetAdapter mInternetAdapter;
-    @Mock
-    private InternetDialogController mInternetDialogController;
-    @Mock
-    private KeyguardStateController mKeyguard;
-    @Mock
-    private DialogTransitionAnimator mDialogTransitionAnimator;
-    @Mock
-    private SystemUIDialog.Factory mSystemUIDialogFactory;
-    @Mock
-    private SystemUIDialog mSystemUIDialog;
-    @Mock
-    private Window mWindow;
-
-    private FakeExecutor mBgExecutor = new FakeExecutor(new FakeSystemClock());
-    private InternetDialogDelegate mInternetDialogDelegate;
-    private View mDialogView;
-    private View mSubTitle;
-    private LinearLayout mEthernet;
-    private LinearLayout mMobileDataLayout;
-    private Switch mMobileToggleSwitch;
-    private LinearLayout mWifiToggle;
-    private Switch mWifiToggleSwitch;
-    private TextView mWifiToggleSummary;
-    private LinearLayout mConnectedWifi;
-    private RecyclerView mWifiList;
-    private LinearLayout mSeeAll;
-    private LinearLayout mWifiScanNotify;
-    private TextView mAirplaneModeSummaryText;
-
-    private MockitoSession mMockitoSession;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt());
-        when(mInternetWifiEntry.getTitle()).thenReturn(WIFI_TITLE);
-        when(mInternetWifiEntry.getSummary(false)).thenReturn(WIFI_SUMMARY);
-        when(mInternetWifiEntry.isDefaultNetwork()).thenReturn(true);
-        when(mInternetWifiEntry.hasInternetAccess()).thenReturn(true);
-        when(mWifiEntries.size()).thenReturn(1);
-
-        when(mInternetDialogController.getMobileNetworkTitle(anyInt()))
-                .thenReturn(MOBILE_NETWORK_TITLE);
-        when(mInternetDialogController.getMobileNetworkSummary(anyInt()))
-                .thenReturn(MOBILE_NETWORK_SUMMARY);
-        when(mInternetDialogController.isWifiEnabled()).thenReturn(true);
-        when(mInternetDialogController.getActiveAutoSwitchNonDdsSubId()).thenReturn(
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        mMockitoSession = ExtendedMockito.mockitoSession()
-                .spyStatic(WifiEnterpriseRestrictionUtils.class)
-                .startMocking();
-        when(WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(mContext)).thenReturn(true);
-        when(mSystemUIDialogFactory.create(any(SystemUIDialog.Delegate.class), eq(mContext)))
-                .thenReturn(mSystemUIDialog);
-        when(mSystemUIDialog.getContext()).thenReturn(mContext);
-        when(mSystemUIDialog.getWindow()).thenReturn(mWindow);
-        createInternetDialog();
-    }
-
-    private void createInternetDialog() {
-        mInternetDialogDelegate = new InternetDialogDelegate(
-                mContext,
-                mock(InternetDialogManager.class),
-                mInternetDialogController,
-                true,
-                true,
-                true,
-                mScope,
-                mock(UiEventLogger.class),
-                mDialogTransitionAnimator,
-                mHandler,
-                mBgExecutor,
-                mKeyguard,
-                mSystemUIDialogFactory,
-                new FakeShadeDialogContextInteractor(mContext));
-        mInternetDialogDelegate.createDialog();
-        mInternetDialogDelegate.onCreate(mSystemUIDialog, null);
-        mInternetDialogDelegate.mAdapter = mInternetAdapter;
-        mInternetDialogDelegate.mConnectedWifiEntry = mInternetWifiEntry;
-        mInternetDialogDelegate.mWifiEntriesCount = mWifiEntries.size();
-
-        mDialogView = mInternetDialogDelegate.mDialogView;
-        mSubTitle = mDialogView.requireViewById(R.id.internet_dialog_subtitle);
-        mEthernet = mDialogView.requireViewById(R.id.ethernet_layout);
-        mMobileDataLayout = mDialogView.requireViewById(R.id.mobile_network_layout);
-        mMobileToggleSwitch = mDialogView.requireViewById(R.id.mobile_toggle);
-        mWifiToggle = mDialogView.requireViewById(R.id.turn_on_wifi_layout);
-        mWifiToggleSwitch = mDialogView.requireViewById(R.id.wifi_toggle);
-        mWifiToggleSummary = mDialogView.requireViewById(R.id.wifi_toggle_summary);
-        mConnectedWifi = mDialogView.requireViewById(R.id.wifi_connected_layout);
-        mWifiList = mDialogView.requireViewById(R.id.wifi_list_layout);
-        mSeeAll = mDialogView.requireViewById(R.id.see_all_layout);
-        mWifiScanNotify = mDialogView.requireViewById(R.id.wifi_scan_notify_layout);
-        mAirplaneModeSummaryText = mDialogView.requireViewById(R.id.airplane_mode_summary);
-        mInternetDialogDelegate.onStart(mSystemUIDialog);
-    }
-
-    @After
-    public void tearDown() {
-        mInternetDialogDelegate.onStop(mSystemUIDialog);
-        mInternetDialogDelegate.dismissDialog();
-        mMockitoSession.finishMocking();
-    }
-
-    @Test
-    public void createInternetDialog_setAccessibilityPaneTitleToQuickSettings() {
-        assertThat(mDialogView.getAccessibilityPaneTitle())
-                .isEqualTo(mContext.getText(R.string.accessibility_desc_quick_settings));
-    }
-
-    @Test
-    public void hideWifiViews_WifiViewsGone() {
-        mInternetDialogDelegate.hideWifiViews();
-
-        assertThat(mInternetDialogDelegate.mIsProgressBarVisible).isFalse();
-        assertThat(mWifiToggle.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mWifiList.getVisibility()).isEqualTo(View.GONE);
-        assertThat(mSeeAll.getVisibility()).isEqualTo(View.GONE);
-    }
-
-    @Test
-    public void updateDialog_withApmOn_internetDialogSubTitleGone() {
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mSubTitle.getVisibility()).isEqualTo(View.VISIBLE);
-                });
-    }
-
-    @Test
-    public void updateDialog_withApmOff_internetDialogSubTitleVisible() {
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mSubTitle.getVisibility()).isEqualTo(View.VISIBLE);
-                });
-    }
-
-    @Test
-    public void updateDialog_apmOffAndHasEthernet_showEthernet() {
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
-        when(mInternetDialogController.hasEthernet()).thenReturn(true);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mEthernet.getVisibility()).isEqualTo(View.VISIBLE);
-                });
-    }
-
-    @Test
-    public void updateDialog_apmOffAndNoEthernet_hideEthernet() {
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
-        when(mInternetDialogController.hasEthernet()).thenReturn(false);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mEthernet.getVisibility()).isEqualTo(View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_apmOnAndHasEthernet_showEthernet() {
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
-        when(mInternetDialogController.hasEthernet()).thenReturn(true);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mEthernet.getVisibility()).isEqualTo(View.VISIBLE);
-                });
-    }
-
-    @Test
-    public void updateDialog_apmOnAndNoEthernet_hideEthernet() {
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
-        when(mInternetDialogController.hasEthernet()).thenReturn(false);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mEthernet.getVisibility()).isEqualTo(View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_apmOffAndNotCarrierNetwork_mobileDataLayoutGone() {
-        // Mobile network should be gone if the list of active subscriptionId is null.
-        when(mInternetDialogController.isCarrierNetworkActive()).thenReturn(false);
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
-        when(mInternetDialogController.hasActiveSubIdOnDds()).thenReturn(false);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mMobileDataLayout.getVisibility()).isEqualTo(View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_apmOnWithCarrierNetworkAndWifiStatus_mobileDataLayoutVisible() {
-        // Carrier network should be visible if airplane mode ON and Wi-Fi is ON.
-        when(mInternetDialogController.isCarrierNetworkActive()).thenReturn(true);
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
-        when(mInternetDialogController.isWifiEnabled()).thenReturn(true);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mMobileDataLayout.getVisibility()).isEqualTo(View.VISIBLE);
-                });
-    }
-
-    @Test
-    public void updateDialog_apmOnWithCarrierNetworkAndWifiStatus_mobileDataLayoutGone() {
-        // Carrier network should be gone if airplane mode ON and Wi-Fi is off.
-        when(mInternetDialogController.isCarrierNetworkActive()).thenReturn(true);
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
-        when(mInternetDialogController.isWifiEnabled()).thenReturn(false);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mMobileDataLayout.getVisibility()).isEqualTo(View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_apmOnAndNoCarrierNetwork_mobileDataLayoutGone() {
-        when(mInternetDialogController.isCarrierNetworkActive()).thenReturn(false);
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mMobileDataLayout.getVisibility()).isEqualTo(View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_apmOnAndWifiOnHasCarrierNetwork_showAirplaneSummary() {
-        when(mInternetDialogController.isCarrierNetworkActive()).thenReturn(true);
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
-        mInternetDialogDelegate.mConnectedWifiEntry = null;
-        doReturn(false).when(mInternetDialogController).activeNetworkIsCellular();
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mMobileDataLayout.getVisibility()).isEqualTo(View.VISIBLE);
-                    assertThat(mAirplaneModeSummaryText.getVisibility()).isEqualTo(View.VISIBLE);
-                });
-    }
-
-    @Test
-    public void updateDialog_apmOffAndWifiOnHasCarrierNetwork_notShowApmSummary() {
-        when(mInternetDialogController.isCarrierNetworkActive()).thenReturn(true);
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
-        mInternetDialogDelegate.mConnectedWifiEntry = null;
-        doReturn(false).when(mInternetDialogController).activeNetworkIsCellular();
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mAirplaneModeSummaryText.getVisibility()).isEqualTo(View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_apmOffAndHasCarrierNetwork_notShowApmSummary() {
-        when(mInternetDialogController.isCarrierNetworkActive()).thenReturn(true);
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mAirplaneModeSummaryText.getVisibility()).isEqualTo(View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_apmOnAndNoCarrierNetwork_notShowApmSummary() {
-        when(mInternetDialogController.isCarrierNetworkActive()).thenReturn(false);
-        when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mAirplaneModeSummaryText.getVisibility()).isEqualTo(View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_mobileDataIsEnabled_checkMobileDataSwitch() {
-        doReturn(true).when(mInternetDialogController).hasActiveSubIdOnDds();
-        when(mInternetDialogController.isCarrierNetworkActive()).thenReturn(true);
-        when(mInternetDialogController.isMobileDataEnabled()).thenReturn(true);
-        mMobileToggleSwitch.setChecked(false);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mMobileToggleSwitch.isChecked()).isTrue();
-                });
-    }
-
-    @Test
-    public void updateDialog_mobileDataIsNotChanged_checkMobileDataSwitch() {
-        doReturn(true).when(mInternetDialogController).hasActiveSubIdOnDds();
-        when(mInternetDialogController.isCarrierNetworkActive()).thenReturn(true);
-        when(mInternetDialogController.isMobileDataEnabled()).thenReturn(false);
-        mMobileToggleSwitch.setChecked(false);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mMobileToggleSwitch.isChecked()).isFalse();
-                });
-    }
-
-    @Test
-    public void updateDialog_wifiOnAndHasInternetWifi_showConnectedWifi() {
-        when(mInternetDialogController.getActiveAutoSwitchNonDdsSubId()).thenReturn(1);
-        doReturn(true).when(mInternetDialogController).hasActiveSubIdOnDds();
-        // The preconditions WiFi ON and Internet WiFi are already in setUp()
-        doReturn(false).when(mInternetDialogController).activeNetworkIsCellular();
-
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.VISIBLE);
-                    LinearLayout secondaryLayout = mDialogView.requireViewById(
-                            R.id.secondary_mobile_network_layout);
-                    assertThat(secondaryLayout.getVisibility()).isEqualTo(View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_wifiOnAndNoConnectedWifi_hideConnectedWifi() {
-        // The precondition WiFi ON is already in setUp()
-        mInternetDialogDelegate.mConnectedWifiEntry = null;
-        doReturn(false).when(mInternetDialogController).activeNetworkIsCellular();
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_wifiOnAndNoWifiEntry_showWifiListAndSeeAllArea() {
-        // The precondition WiFi ON is already in setUp()
-        mInternetDialogDelegate.mConnectedWifiEntry = null;
-        mInternetDialogDelegate.mWifiEntriesCount = 0;
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
-                    // Show a blank block to fix the dialog height even if there is no WiFi list
-                    assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
-                    verify(mInternetAdapter).setMaxEntriesCount(3);
-                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.INVISIBLE);
-                });
-    }
-
-    @Test
-    public void updateDialog_wifiOnAndOneWifiEntry_showWifiListAndSeeAllArea() {
-        // The precondition WiFi ON is already in setUp()
-        mInternetDialogDelegate.mConnectedWifiEntry = null;
-        mInternetDialogDelegate.mWifiEntriesCount = 1;
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
-                    // Show a blank block to fix the dialog height even if there is no WiFi list
-                    assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
-                    verify(mInternetAdapter).setMaxEntriesCount(3);
-                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.INVISIBLE);
-                });
-    }
-
-    @Test
-    public void updateDialog_wifiOnAndHasConnectedWifi_showAllWifiAndSeeAllArea() {
-        // The preconditions WiFi ON and WiFi entries are already in setUp()
-        mInternetDialogDelegate.mWifiEntriesCount = 0;
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.VISIBLE);
-                    // Show a blank block to fix the dialog height even if there is no WiFi list
-                    assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
-                    verify(mInternetAdapter).setMaxEntriesCount(2);
-                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.INVISIBLE);
-                });
-    }
-
-    @Test
-    public void updateDialog_wifiOnAndHasMaxWifiList_showWifiListAndSeeAll() {
-        // The preconditions WiFi ON and WiFi entries are already in setUp()
-        mInternetDialogDelegate.mConnectedWifiEntry = null;
-        mInternetDialogDelegate.mWifiEntriesCount = MAX_WIFI_ENTRY_COUNT;
-        mInternetDialogDelegate.mHasMoreWifiEntries = true;
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
-                    assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
-                    verify(mInternetAdapter).setMaxEntriesCount(3);
-                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.VISIBLE);
-                });
-    }
-
-    @Test
-    public void updateDialog_wifiOnAndHasBothWifiEntry_showBothWifiEntryAndSeeAll() {
-        // The preconditions WiFi ON and WiFi entries are already in setUp()
-        mInternetDialogDelegate.mWifiEntriesCount = MAX_WIFI_ENTRY_COUNT - 1;
-        mInternetDialogDelegate.mHasMoreWifiEntries = true;
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.VISIBLE);
-                    assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
-                    verify(mInternetAdapter).setMaxEntriesCount(2);
-                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.VISIBLE);
-                });
-    }
-
-    @Test
-    public void updateDialog_deviceLockedAndNoConnectedWifi_showWifiToggle() {
-        // The preconditions WiFi entries are already in setUp()
-        when(mInternetDialogController.isDeviceLocked()).thenReturn(true);
-        mInternetDialogDelegate.mConnectedWifiEntry = null;
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    // Show WiFi Toggle without background
-                    assertThat(mWifiToggle.getVisibility()).isEqualTo(View.VISIBLE);
-                    assertThat(mWifiToggle.getBackground()).isNull();
-                    // Hide Wi-Fi networks and See all
-                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
-                    assertThat(mWifiList.getVisibility()).isEqualTo(View.GONE);
-                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_deviceLockedAndHasConnectedWifi_showWifiToggleWithBackground() {
-        // The preconditions WiFi ON and WiFi entries are already in setUp()
-        when(mInternetDialogController.isDeviceLocked()).thenReturn(true);
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    // Show WiFi Toggle with highlight background
-                    assertThat(mWifiToggle.getVisibility()).isEqualTo(View.VISIBLE);
-                    assertThat(mWifiToggle.getBackground()).isNotNull();
-                    // Hide Wi-Fi networks and See all
-                    assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
-                    assertThat(mWifiList.getVisibility()).isEqualTo(View.GONE);
-                    assertThat(mSeeAll.getVisibility()).isEqualTo(View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_disallowChangeWifiState_disableWifiSwitch() {
-        mInternetDialogDelegate.dismissDialog();
-        when(WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(mContext)).thenReturn(false);
-        createInternetDialog();
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    // Disable Wi-Fi switch and show restriction message in summary.
-                    assertThat(mWifiToggleSwitch.isEnabled()).isFalse();
-                    assertThat(mWifiToggleSummary.getVisibility()).isEqualTo(View.VISIBLE);
-                    assertThat(mWifiToggleSummary.getText().length()).isNotEqualTo(0);
-                });
-    }
-
-    @Test
-    public void updateDialog_allowChangeWifiState_enableWifiSwitch() {
-        mInternetDialogDelegate.dismissDialog();
-        when(WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(mContext)).thenReturn(true);
-        createInternetDialog();
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    // Enable Wi-Fi switch and hide restriction message in summary.
-                    assertThat(mWifiToggleSwitch.isEnabled()).isTrue();
-                    assertThat(mWifiToggleSummary.getVisibility()).isEqualTo(View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_showSecondaryDataSub() {
-        when(mInternetDialogController.getActiveAutoSwitchNonDdsSubId()).thenReturn(1);
-        doReturn(1).when(mInternetDialogController).getActiveAutoSwitchNonDdsSubId();
-        doReturn(true).when(mInternetDialogController).hasActiveSubIdOnDds();
-        doReturn(false).when(mInternetDialogController).isAirplaneModeEnabled();
-        clearInvocations(mInternetDialogController);
-        mInternetDialogDelegate.updateDialog(true);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    LinearLayout primaryLayout = mDialogView.requireViewById(
-                            R.id.mobile_network_layout);
-                    LinearLayout secondaryLayout = mDialogView.requireViewById(
-                            R.id.secondary_mobile_network_layout);
-
-                    verify(mInternetDialogController).getMobileNetworkSummary(1);
-                    assertThat(primaryLayout.getBackground()).isNotEqualTo(
-                            secondaryLayout.getBackground());
-                });
-    }
-
-    @Test
-    public void updateDialog_wifiOn_hideWifiScanNotify() {
-        // The preconditions WiFi ON and WiFi entries are already in setUp()
-
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
-                });
-
-        assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
-    }
-
-    @Test
-    public void updateDialog_wifiOffAndWifiScanOff_hideWifiScanNotify() {
-        when(mInternetDialogController.isWifiEnabled()).thenReturn(false);
-        when(mInternetDialogController.isWifiScanEnabled()).thenReturn(false);
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
-                });
-
-        assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
-    }
-
-    @Test
-    public void updateDialog_wifiOffAndWifiScanOnAndDeviceLocked_hideWifiScanNotify() {
-        when(mInternetDialogController.isWifiEnabled()).thenReturn(false);
-        when(mInternetDialogController.isWifiScanEnabled()).thenReturn(true);
-        when(mInternetDialogController.isDeviceLocked()).thenReturn(true);
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
-                });
-
-        assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.GONE);
-    }
-
-    @Test
-    public void updateDialog_wifiOffAndWifiScanOnAndDeviceUnlocked_showWifiScanNotify() {
-        when(mInternetDialogController.isWifiEnabled()).thenReturn(false);
-        when(mInternetDialogController.isWifiScanEnabled()).thenReturn(true);
-        when(mInternetDialogController.isDeviceLocked()).thenReturn(false);
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mWifiScanNotify.getVisibility()).isEqualTo(View.VISIBLE);
-                    TextView wifiScanNotifyText = mDialogView.requireViewById(
-                            R.id.wifi_scan_notify_text);
-                    assertThat(wifiScanNotifyText.getText().length()).isNotEqualTo(0);
-                    assertThat(wifiScanNotifyText.getMovementMethod()).isNotNull();
-                });
-    }
-
-    @Test
-    public void updateDialog_wifiIsDisabled_uncheckWifiSwitch() {
-        when(mInternetDialogController.isWifiEnabled()).thenReturn(false);
-        mWifiToggleSwitch.setChecked(true);
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mWifiToggleSwitch.isChecked()).isFalse();
-                });
-    }
-
-    @Test
-    public void updateDialog_wifiIsEnabled_checkWifiSwitch() throws Exception {
-        when(mInternetDialogController.isWifiEnabled()).thenReturn(true);
-        mWifiToggleSwitch.setChecked(false);
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mWifiToggleSwitch.isChecked()).isTrue();
-                });
-    }
-
-    @Test
-    public void onClickSeeMoreButton_clickSeeAll_verifyLaunchNetworkSetting() {
-        mSeeAll.performClick();
-
-        verify(mInternetDialogController).launchNetworkSetting(
-                mDialogView.requireViewById(R.id.see_all_layout));
-    }
-
-    @Test
-    public void onWifiScan_isScanTrue_setProgressBarVisibleTrue() {
-        mInternetDialogDelegate.mIsProgressBarVisible = false;
-
-        mInternetDialogDelegate.onWifiScan(true);
-
-        assertThat(mInternetDialogDelegate.mIsProgressBarVisible).isTrue();
-    }
-
-    @Test
-    public void onWifiScan_isScanFalse_setProgressBarVisibleFalse() {
-        mInternetDialogDelegate.mIsProgressBarVisible = true;
-
-        mInternetDialogDelegate.onWifiScan(false);
-
-        assertThat(mInternetDialogDelegate.mIsProgressBarVisible).isFalse();
-    }
-
-    @Test
-    public void getWifiListMaxCount_returnCountCorrectly() {
-        // Both of the Ethernet, MobileData is hidden.
-        // Then the maximum count is equal to MAX_WIFI_ENTRY_COUNT.
-        setNetworkVisible(false, false, false);
-
-        assertThat(mInternetDialogDelegate.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT);
-
-        // If the Connected Wi-Fi is displayed then reduce one of the Wi-Fi list max count.
-        setNetworkVisible(false, false, true);
-
-        assertThat(mInternetDialogDelegate.getWifiListMaxCount())
-                .isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
-
-        // Only one of Ethernet, MobileData is displayed.
-        // Then the maximum count is equal to MAX_WIFI_ENTRY_COUNT.
-        setNetworkVisible(true, false, false);
-
-        assertThat(mInternetDialogDelegate.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT);
-
-        setNetworkVisible(false, true, false);
-
-        assertThat(mInternetDialogDelegate.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT);
-
-        // If the Connected Wi-Fi is displayed then reduce one of the Wi-Fi list max count.
-        setNetworkVisible(true, false, true);
-
-        assertThat(mInternetDialogDelegate.getWifiListMaxCount())
-                .isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
-
-        setNetworkVisible(false, true, true);
-
-        assertThat(mInternetDialogDelegate.getWifiListMaxCount())
-                .isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
-
-        // Both of Ethernet, MobileData, ConnectedWiFi is displayed.
-        // Then the maximum count is equal to MAX_WIFI_ENTRY_COUNT - 1.
-        setNetworkVisible(true, true, false);
-
-        assertThat(mInternetDialogDelegate.getWifiListMaxCount())
-                .isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
-
-        // If the Connected Wi-Fi is displayed then reduce one of the Wi-Fi list max count.
-        setNetworkVisible(true, true, true);
-
-        assertThat(mInternetDialogDelegate.getWifiListMaxCount())
-                .isEqualTo(MAX_WIFI_ENTRY_COUNT - 2);
-    }
-
-    @Test
-    public void updateDialog_shareWifiIntentNull_hideButton() {
-        when(mInternetDialogController.getConfiguratorQrCodeGeneratorIntentOrNull(any()))
-                .thenReturn(null);
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mInternetDialogDelegate.mShareWifiButton.getVisibility()).isEqualTo(
-                            View.GONE);
-                });
-    }
-
-    @Test
-    public void updateDialog_shareWifiShareable_showButton() {
-        when(mInternetDialogController.getConfiguratorQrCodeGeneratorIntentOrNull(any()))
-                .thenReturn(new Intent());
-        mInternetDialogDelegate.updateDialog(false);
-        mBgExecutor.runAllReady();
-
-        mInternetDialogDelegate.mDataInternetContent.observe(
-                mInternetDialogDelegate.mLifecycleOwner, i -> {
-                    assertThat(mInternetDialogDelegate.mShareWifiButton.getVisibility())
-                            .isEqualTo(View.VISIBLE);
-                });
-    }
-
-    private void setNetworkVisible(boolean ethernetVisible, boolean mobileDataVisible,
-            boolean connectedWifiVisible) {
-        mEthernet.setVisibility(ethernetVisible ? View.VISIBLE : View.GONE);
-        mMobileDataLayout.setVisibility(mobileDataVisible ? View.VISIBLE : View.GONE);
-        mConnectedWifi.setVisibility(connectedWifiVisible ? View.VISIBLE : View.GONE);
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
index afff485..a17f100 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
@@ -36,6 +36,7 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
+import android.media.projection.StopReason;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
@@ -154,7 +155,7 @@
         PendingIntent stopIntent = Mockito.mock(PendingIntent.class);
 
         mController.startCountdown(0, 0, startIntent, stopIntent);
-        mController.stopRecording();
+        mController.stopRecording(StopReason.STOP_UNKNOWN);
 
         assertFalse(mController.isStarting());
         assertFalse(mController.isRecording());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/DisplayTrackerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/DisplayTrackerImplTest.kt
index 9fb752a..4471c58 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/DisplayTrackerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/DisplayTrackerImplTest.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.settings
 
 import android.hardware.display.DisplayManager
-import android.hardware.display.DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS
+import android.hardware.display.DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS
 import android.hardware.display.DisplayManagerGlobal
 import android.os.Handler
 import android.testing.AndroidTestingRunner
@@ -98,7 +98,7 @@
                 any(),
                 any(),
                 eq(0L),
-                eq(PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS),
+                eq(PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS),
             )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
index c410111..6724f82 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -699,6 +699,30 @@
             }
         }
 
+    @Test
+    fun onTouchEvent_qsExpanding_touchesNotDispatched() =
+        with(kosmos) {
+            testScope.runTest {
+                // On lockscreen.
+                goToScene(CommunalScenes.Blank)
+                whenever(
+                        notificationStackScrollLayoutController.isBelowLastNotification(
+                            any(),
+                            any(),
+                        )
+                    )
+                    .thenReturn(true)
+
+                // Shade is open slightly.
+                shadeTestUtil.setQsExpansion(0.01f)
+                testableLooper.processAllMessages()
+
+                // Touches are not consumed.
+                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
+                verify(containerView, never()).onTouchEvent(DOWN_EVENT)
+            }
+        }
+
     @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
     @Test
     fun onTouchEvent_bouncerInteracting_movesNotDispatched() =
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 4b11e2c..e68153a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -22,6 +22,7 @@
 import android.platform.test.flag.junit.FlagsParameterization
 import android.testing.TestableLooper
 import android.testing.TestableLooper.RunWithLooper
+import android.view.Choreographer
 import android.view.KeyEvent
 import android.view.MotionEvent
 import android.view.View
@@ -57,6 +58,7 @@
 import com.android.systemui.settings.brightness.domain.interactor.BrightnessMirrorShowingInteractor
 import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
 import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
+import com.android.systemui.statusbar.BlurUtils
 import com.android.systemui.statusbar.DragDownHelper
 import com.android.systemui.statusbar.LockscreenShadeTransitionController
 import com.android.systemui.statusbar.NotificationInsetsController
@@ -80,6 +82,7 @@
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.window.ui.viewmodel.WindowRootViewModel
 import com.google.common.truth.Truth.assertThat
 import java.util.Optional
 import kotlinx.coroutines.Dispatchers
@@ -155,6 +158,9 @@
     @Mock lateinit var sysUIKeyEventHandler: SysUIKeyEventHandler
     @Mock lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
     @Mock lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
+    @Mock private lateinit var blurUtils: BlurUtils
+    @Mock private lateinit var choreographer: Choreographer
+    @Mock private lateinit var windowViewModelFactory: WindowRootViewModel.Factory
     private val notificationLaunchAnimationRepository = NotificationLaunchAnimationRepository()
     private val notificationLaunchAnimationInteractor =
         NotificationLaunchAnimationInteractor(notificationLaunchAnimationRepository)
@@ -203,6 +209,9 @@
         fakeClock = FakeSystemClock()
         underTest =
             NotificationShadeWindowViewController(
+                blurUtils,
+                windowViewModelFactory,
+                choreographer,
                 lockscreenShadeTransitionController,
                 falsingCollector,
                 sysuiStatusBarStateController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
index 2d35ea5..61943f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
@@ -65,7 +65,7 @@
 import com.android.systemui.statusbar.notification.NotificationActivityStarter
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider
 import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
-import com.android.systemui.statusbar.notification.headsup.headsUpManager
+import com.android.systemui.statusbar.notification.headsup.mockHeadsUpManager
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.statusbar.notificationLockscreenUserManager
@@ -128,7 +128,7 @@
     private val shadeController = kosmos.shadeControllerSceneImpl
     private val notificationLockscreenUserManager = kosmos.notificationLockscreenUserManager
     private val statusBarStateController = kosmos.statusBarStateController
-    private val headsUpManager = kosmos.headsUpManager
+    private val headsUpManager = kosmos.mockHeadsUpManager
     private val activityStarter = kosmos.activityStarter
     private val userManager = kosmos.userManager
     private val activeNotificationsInteractor = kosmos.activeNotificationsInteractor
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 411c81d13..1fcf02d 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
@@ -36,6 +36,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static kotlinx.coroutines.flow.FlowKt.flowOf;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -54,8 +56,6 @@
 
 import static java.util.Collections.emptySet;
 
-import static kotlinx.coroutines.flow.FlowKt.flowOf;
-
 import android.app.ActivityManager;
 import android.app.IWallpaperManager;
 import android.app.NotificationManager;
@@ -132,6 +132,7 @@
 import com.android.systemui.notetask.NoteTaskController;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.PluginDependencyProvider;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -175,6 +176,7 @@
 import com.android.systemui.statusbar.core.StatusBarConnectedDisplays;
 import com.android.systemui.statusbar.core.StatusBarInitializerImpl;
 import com.android.systemui.statusbar.data.repository.FakeStatusBarModeRepository;
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController;
 import com.android.systemui.statusbar.data.repository.StatusBarModePerDisplayRepository;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
@@ -216,6 +218,10 @@
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.startingsurface.StartingSurface;
 
+import dagger.Lazy;
+
+import kotlinx.coroutines.test.TestScope;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -232,9 +238,6 @@
 
 import javax.inject.Provider;
 
-import dagger.Lazy;
-import kotlinx.coroutines.test.TestScope;
-
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 @RunWithLooper(setAsMainLooper = true)
@@ -536,6 +539,8 @@
                 new StatusBarInitializerImpl(
                         mStatusBarWindowController,
                         mStatusBarModePerDisplayRepository,
+                        mock(StatusBarConfigurationController.class),
+                        mock(DarkIconDispatcher.class),
                         mCollapsedStatusBarFragmentProvider,
                         mock(StatusBarRootFactory.class),
                         mock(HomeStatusBarComponent.Factory.class),
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 0b443675..3a99328 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
@@ -25,6 +25,7 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -61,6 +62,9 @@
 import com.android.systemui.statusbar.OperatorNameViewController;
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
 import com.android.systemui.statusbar.core.StatusBarRootModernization;
+import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore;
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController;
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore;
 import com.android.systemui.statusbar.disableflags.DisableFlagsLogger;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
 import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder;
@@ -75,6 +79,8 @@
 import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.FakeHomeStatusBarViewModel;
 import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.StatusBarOperatorNameViewModel;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.window.StatusBarWindowController;
+import com.android.systemui.statusbar.window.StatusBarWindowControllerStore;
 import com.android.systemui.statusbar.window.StatusBarWindowStateController;
 import com.android.systemui.statusbar.window.StatusBarWindowStateListener;
 import com.android.systemui.util.CarrierConfigTracker;
@@ -134,6 +140,12 @@
     private StatusBarWindowStateController mStatusBarWindowStateController;
     @Mock
     private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    @Mock private StatusBarWindowControllerStore mStatusBarWindowControllerStore;
+    @Mock private StatusBarWindowController mStatusBarWindowController;
+    @Mock private StatusBarConfigurationControllerStore mStatusBarConfigurationControllerStore;
+    @Mock private StatusBarConfigurationController mStatusBarConfigurationController;
+    @Mock private DarkIconDispatcherStore mDarkIconDispatcherStore;
+    @Mock private DarkIconDispatcher mDarkIconDispatcher;
     @Rule
     public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule(this);
 
@@ -145,6 +157,12 @@
 
     @Before
     public void setup() {
+        when(mStatusBarWindowControllerStore.forDisplay(anyInt()))
+                .thenReturn(mStatusBarWindowController);
+        when(mStatusBarConfigurationControllerStore.forDisplay(anyInt()))
+                .thenReturn(mStatusBarConfigurationController);
+        when(mDarkIconDispatcherStore.forDisplay(anyInt())).thenReturn(mDarkIconDispatcher);
+
         injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
         mDependency.injectMockDependency(DarkIconDispatcher.class);
 
@@ -1276,11 +1294,14 @@
                 mDumpManager,
                 mStatusBarWindowStateController,
                 mKeyguardUpdateMonitor,
-                mock(DemoModeController.class));
+                mock(DemoModeController.class),
+                mStatusBarWindowControllerStore,
+                mStatusBarConfigurationControllerStore,
+                mDarkIconDispatcherStore);
     }
 
     private void setUpDaggerComponent() {
-        when(mStatusBarFragmentComponentFactory.create(any()))
+        when(mStatusBarFragmentComponentFactory.create(any(), any(), any(), any()))
                 .thenReturn(mHomeStatusBarComponent);
         when(mHomeStatusBarComponent.getHeadsUpAppearanceController())
                 .thenReturn(mHeadsUpAppearanceController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 192d66c..7508838 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -167,7 +167,6 @@
 import com.android.systemui.util.time.SystemClock;
 import com.android.wm.shell.Flags;
 import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.bubbles.Bubble;
 import com.android.wm.shell.bubbles.BubbleData;
 import com.android.wm.shell.bubbles.BubbleDataRepository;
@@ -184,6 +183,8 @@
 import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
 import com.android.wm.shell.bubbles.properties.BubbleProperties;
 import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.DisplayInsetsController;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
@@ -197,6 +198,7 @@
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.taskview.TaskView;
+import com.android.wm.shell.taskview.TaskViewRepository;
 import com.android.wm.shell.taskview.TaskViewTransitions;
 import com.android.wm.shell.transition.Transitions;
 
@@ -325,7 +327,9 @@
     @Mock
     private LauncherApps mLauncherApps;
     @Mock
-    private WindowManagerShellWrapper mWindowManagerShellWrapper;
+    private DisplayInsetsController mDisplayInsetsController;
+    @Mock
+    private DisplayImeController mDisplayImeController;
     @Mock
     private BubbleLogger mBubbleLogger;
     @Mock
@@ -359,6 +363,7 @@
     private ShadeInteractor mShadeInteractor;
     private NotificationShadeWindowModel mNotificationShadeWindowModel;
     private ShellTaskOrganizer mShellTaskOrganizer;
+    private TaskViewRepository mTaskViewRepository;
     private TaskViewTransitions mTaskViewTransitions;
 
     private TestableBubblePositioner mPositioner;
@@ -395,7 +400,8 @@
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
             doReturn(true).when(mTransitions).isRegistered();
         }
-        mTaskViewTransitions = new TaskViewTransitions(mTransitions);
+        mTaskViewRepository = new TaskViewRepository();
+        mTaskViewTransitions = new TaskViewTransitions(mTransitions, mTaskViewRepository);
 
         mTestableLooper = TestableLooper.get(this);
 
@@ -503,7 +509,7 @@
                         mContext,
                         mock(NotificationManager.class),
                         mock(NotificationSettingsInteractor.class)
-                        );
+                );
         interruptionDecisionProvider.start();
 
         mShellTaskOrganizer = new ShellTaskOrganizer(mock(ShellInit.class),
@@ -523,7 +529,8 @@
                 mDataRepository,
                 mStatusBarService,
                 mWindowManager,
-                mWindowManagerShellWrapper,
+                mDisplayInsetsController,
+                mDisplayImeController,
                 mUserManager,
                 mLauncherApps,
                 mBubbleLogger,
@@ -1430,9 +1437,12 @@
                 mPositioner,
                 mBubbleController.getStackView(),
                 new BubbleIconFactory(mContext,
-                        mContext.getResources().getDimensionPixelSize(com.android.wm.shell.R.dimen.bubble_size),
-                        mContext.getResources().getDimensionPixelSize(com.android.wm.shell.R.dimen.bubble_badge_size),
-                        mContext.getResources().getColor(com.android.launcher3.icons.R.color.important_conversation),
+                        mContext.getResources().getDimensionPixelSize(
+                                com.android.wm.shell.R.dimen.bubble_size),
+                        mContext.getResources().getDimensionPixelSize(
+                                com.android.wm.shell.R.dimen.bubble_badge_size),
+                        mContext.getResources().getColor(
+                                com.android.launcher3.icons.R.color.important_conversation),
                         mContext.getResources().getDimensionPixelSize(
                                 com.android.internal.R.dimen.importance_ring_stroke_width)),
                 bubble,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
index b8be6aa..64d89c5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
@@ -81,6 +81,14 @@
         return super.getDisplay();
     }
 
+    @Override
+    public int getDisplayId() {
+        if (mCustomDisplay != null) {
+            return mCustomDisplay.getDisplayId();
+        }
+        return super.getDisplayId();
+    }
+
     public SysuiTestableContext createDefaultDisplayContext() {
         Display display = getBaseContext().getSystemService(DisplayManager.class).getDisplays()[0];
         return (SysuiTestableContext) createDisplayContext(display);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FeatureFlagsClassicKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FeatureFlagsClassicKosmos.kt
index d9235cc..2f7936a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FeatureFlagsClassicKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FeatureFlagsClassicKosmos.kt
@@ -34,7 +34,6 @@
     Kosmos.Fixture {
         FakeFeatureFlagsClassic().apply {
             set(Flags.FULL_SCREEN_USER_SWITCHER, false)
-            set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, false)
             set(Flags.LOCKSCREEN_ENABLE_LANDSCAPE, false)
             set(Flags.NSSL_DEBUG_LINES, false)
             set(Flags.COMMUNAL_SERVICE_ENABLED, false)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt
index 6df2318c..d59b5d5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/KeyguardBlueprintRepositoryKosmos.kt
@@ -63,7 +63,6 @@
             defaultNotificationStackScrollLayoutSection = mock(),
             aodNotificationIconsSection = mock(),
             aodBurnInSection = mock(),
-            communalTutorialIndicatorSection = mock(),
             clockSection = keyguardClockSection,
             smartspaceSection = keyguardSmartspaceSection,
             keyguardSliceViewSection = mock(),
@@ -85,7 +84,6 @@
             splitShadeGuidelines = mock(),
             aodNotificationIconsSection = mock(),
             aodBurnInSection = mock(),
-            communalTutorialIndicatorSection = mock(),
             clockSection = keyguardClockSection,
             smartspaceSection = keyguardSmartspaceSection,
             mediaSection = mock(),
diff --git a/nfc/java/android/nfc/OemLogItems.aidl b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/transitions/BlurConfigKosmos.kt
similarity index 71%
copy from nfc/java/android/nfc/OemLogItems.aidl
copy to packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/transitions/BlurConfigKosmos.kt
index 3bcb445..0e24805 100644
--- a/nfc/java/android/nfc/OemLogItems.aidl
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/transitions/BlurConfigKosmos.kt
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
-package android.nfc;
+package com.android.systemui.keyguard.ui.transitions
 
-parcelable OemLogItems;
\ No newline at end of file
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.blurConfig by Fixture { BlurConfig(minBlurRadiusPx = 1.0f, maxBlurRadiusPx = 100.0f) }
diff --git a/nfc/java/android/nfc/OemLogItems.aidl b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/transitions/FakeBouncerTransition.kt
similarity index 71%
copy from nfc/java/android/nfc/OemLogItems.aidl
copy to packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/transitions/FakeBouncerTransition.kt
index 3bcb445..15d00d9 100644
--- a/nfc/java/android/nfc/OemLogItems.aidl
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/transitions/FakeBouncerTransition.kt
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
-package android.nfc;
+package com.android.systemui.keyguard.ui.transitions
 
-parcelable OemLogItems;
\ No newline at end of file
+import kotlinx.coroutines.flow.MutableStateFlow
+
+class FakeBouncerTransition : PrimaryBouncerTransition {
+    override val windowBlurRadius: MutableStateFlow<Float> = MutableStateFlow(0.0f)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelKosmos.kt
index b03624b..7989244 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelKosmos.kt
@@ -19,13 +19,16 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
+@OptIn(ExperimentalCoroutinesApi::class)
 val Kosmos.alternateBouncerToPrimaryBouncerTransitionViewModel by Fixture {
     AlternateBouncerToPrimaryBouncerTransitionViewModel(
         animationFlow = keyguardTransitionAnimationFlow,
         shadeDependentFlows = shadeDependentFlows,
+        blurConfig = blurConfig,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerViewModelKosmos.kt
index 5e6d605..faa290be 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerViewModelKosmos.kt
@@ -17,11 +17,15 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
 @OptIn(ExperimentalCoroutinesApi::class)
 val Kosmos.aodToPrimaryBouncerTransitionViewModel by Fixture {
-    AodToPrimaryBouncerTransitionViewModel(animationFlow = keyguardTransitionAnimationFlow)
+    AodToPrimaryBouncerTransitionViewModel(
+        animationFlow = keyguardTransitionAnimationFlow,
+        blurConfig = blurConfig,
+    )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelKosmos.kt
index dc6b26f..d3ccb29 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModelKosmos.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -25,5 +26,6 @@
 val Kosmos.dozingToPrimaryBouncerTransitionViewModel by Fixture {
     DozingToPrimaryBouncerTransitionViewModel(
         animationFlow = keyguardTransitionAnimationFlow,
+        blurConfig = blurConfig,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..c1c0807
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModelKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 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.keyguard.ui.viewmodel
+
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.blurConfig
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.glanceableHubToPrimaryBouncerTransitionViewModel by Fixture {
+    GlanceableHubToPrimaryBouncerTransitionViewModel(
+        animationFlow = keyguardTransitionAnimationFlow,
+        blurConfig = blurConfig,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelKosmos.kt
index f094f22..68280d7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelKosmos.kt
@@ -19,6 +19,7 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -27,5 +28,6 @@
     LockscreenToPrimaryBouncerTransitionViewModel(
         shadeDependentFlows = shadeDependentFlows,
         animationFlow = keyguardTransitionAnimationFlow,
+        blurConfig = blurConfig,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..004f97d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModelKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 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.keyguard.ui.viewmodel
+
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.blurConfig
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.occludedToPrimaryBouncerTransitionViewModel by Fixture {
+    OccludedToPrimaryBouncerTransitionViewModel(
+        animationFlow = keyguardTransitionAnimationFlow,
+        blurConfig = blurConfig,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelKosmos.kt
index 8d88730..043a49f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModelKosmos.kt
@@ -20,6 +20,7 @@
 
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
 import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -28,5 +29,6 @@
     PrimaryBouncerToAodTransitionViewModel(
         deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
         animationFlow = keyguardTransitionAnimationFlow,
+        blurConfig = blurConfig,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelKosmos.kt
index d4e4b8c..59ea2c9 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModelKosmos.kt
@@ -18,6 +18,7 @@
 
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
 import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -27,5 +28,6 @@
     PrimaryBouncerToDozingTransitionViewModel(
         deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
         animationFlow = keyguardTransitionAnimationFlow,
+        blurConfig = blurConfig,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModelKosmos.kt
index 09233af..4fe18fb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModelKosmos.kt
@@ -17,11 +17,13 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 
 val Kosmos.primaryBouncerToGlanceableHubTransitionViewModel by Fixture {
     PrimaryBouncerToGlanceableHubTransitionViewModel(
-        animationFlow = keyguardTransitionAnimationFlow
+        animationFlow = keyguardTransitionAnimationFlow,
+        blurConfig = blurConfig,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelKosmos.kt
index d6edea2..b470ab1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelKosmos.kt
@@ -21,6 +21,7 @@
 import com.android.systemui.bouncer.domain.interactor.mockPrimaryBouncerInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardDismissActionInteractor
 import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.statusbar.sysuiStatusBarStateController
@@ -33,5 +34,6 @@
         keyguardDismissActionInteractor = { keyguardDismissActionInteractor },
         bouncerToGoneFlows = bouncerToGoneFlows,
         animationFlow = keyguardTransitionAnimationFlow,
+        blurConfig = blurConfig,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelKosmos.kt
index 76478cb..c344775 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelKosmos.kt
@@ -19,6 +19,7 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.blurConfig
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -27,5 +28,6 @@
     PrimaryBouncerToLockscreenTransitionViewModel(
         animationFlow = keyguardTransitionAnimationFlow,
         shadeDependentFlows = shadeDependentFlows,
+        blurConfig = blurConfig,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModelKosmos.kt
new file mode 100644
index 0000000..2256c10
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModelKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 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.keyguard.ui.viewmodel
+
+import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.blurConfig
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.primaryBouncerToOccludedTransitionViewModel by Fixture {
+    PrimaryBouncerToOccludedTransitionViewModel(
+        animationFlow = keyguardTransitionAnimationFlow,
+        blurConfig = blurConfig,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/FakeMediaControllerFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/FakeMediaControllerFactory.kt
index b833750..b20678e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/FakeMediaControllerFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/FakeMediaControllerFactory.kt
@@ -35,7 +35,7 @@
         return mediaControllersForToken[token]!!
     }
 
-    override suspend fun create(token: SessionToken, looper: Looper): Media3Controller {
+    override suspend fun create(token: SessionToken, looper: Looper): Media3Controller? {
         return media3Controller ?: super.create(token, looper)
     }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/FakeMediaRouterRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/FakeMediaRouterRepository.kt
index 8aa7a03..d5637cb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/FakeMediaRouterRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/FakeMediaRouterRepository.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.mediarouter.data.repository
 
+import android.media.projection.StopReason
 import com.android.systemui.statusbar.policy.CastDevice
 import kotlinx.coroutines.flow.MutableStateFlow
 
@@ -25,7 +26,7 @@
     var lastStoppedDevice: CastDevice? = null
         private set
 
-    override fun stopCasting(device: CastDevice) {
+    override fun stopCasting(device: CastDevice, @StopReason stopReason: Int) {
         lastStoppedDevice = device
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/screenrecord/data/repository/FakeScreenRecordRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/screenrecord/data/repository/FakeScreenRecordRepository.kt
index 30b4763..4c9e174 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/screenrecord/data/repository/FakeScreenRecordRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/screenrecord/data/repository/FakeScreenRecordRepository.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.screenrecord.data.repository
 
+import android.media.projection.StopReason
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
 import kotlinx.coroutines.flow.MutableStateFlow
 
@@ -25,7 +26,7 @@
 
     var stopRecordingInvoked = false
 
-    override suspend fun stopRecording() {
+    override suspend fun stopRecording(@StopReason stopReason: Int) {
         stopRecordingInvoked = true
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarInitializerFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarInitializerFactory.kt
index 50a19a9..fb2e2a3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarInitializerFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/FakeStatusBarInitializerFactory.kt
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.core
 
+import com.android.systemui.plugins.DarkIconDispatcher
+import com.android.systemui.statusbar.data.repository.StatusBarConfigurationController
 import com.android.systemui.statusbar.data.repository.StatusBarModePerDisplayRepository
 import com.android.systemui.statusbar.window.StatusBarWindowController
 
@@ -24,5 +26,7 @@
     override fun create(
         statusBarWindowController: StatusBarWindowController,
         statusBarModePerDisplayRepository: StatusBarModePerDisplayRepository,
+        statusBarConfigurationController: StatusBarConfigurationController,
+        darkIconDispatcher: DarkIconDispatcher,
     ): StatusBarInitializer = FakeStatusBarInitializer()
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarInitializerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarInitializerKosmos.kt
index 6e99027..b8dafb2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarInitializerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/core/StatusBarInitializerKosmos.kt
@@ -19,7 +19,9 @@
 import com.android.systemui.display.data.repository.displayRepository
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.statusbar.data.repository.darkIconDispatcherStore
 import com.android.systemui.statusbar.data.repository.fakeStatusBarModeRepository
+import com.android.systemui.statusbar.data.repository.statusBarConfigurationControllerStore
 import com.android.systemui.statusbar.window.fakeStatusBarWindowControllerStore
 
 val Kosmos.fakeStatusBarInitializer by Kosmos.Fixture { FakeStatusBarInitializer() }
@@ -39,6 +41,8 @@
             fakeStatusBarInitializerFactory,
             fakeStatusBarWindowControllerStore,
             fakeStatusBarModeRepository,
+            statusBarConfigurationControllerStore,
+            darkIconDispatcherStore,
         )
     }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorKosmos.kt
index 0025ad4..f7e235a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorKosmos.kt
@@ -17,13 +17,13 @@
 package com.android.systemui.statusbar.featurepods.media.domain.interactor
 
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.backgroundScope
 import com.android.systemui.media.controls.data.repository.mediaFilterRepository
 
 val Kosmos.mediaControlChipInteractor: MediaControlChipInteractor by
     Kosmos.Fixture {
         MediaControlChipInteractor(
-            applicationScope = applicationCoroutineScope,
+            backgroundScope = backgroundScope,
             mediaFilterRepository = mediaFilterRepository,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelKosmos.kt
new file mode 100644
index 0000000..7145907
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/ui/viewmodel/MediaControlChipViewModelKosmos.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 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.featurepods.media.ui.viewmodel
+
+import android.content.testableContext
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.statusbar.featurepods.media.domain.interactor.mediaControlChipInteractor
+
+val Kosmos.mediaControlChipViewModel: MediaControlChipViewModel by
+    Kosmos.Fixture {
+        MediaControlChipViewModel(
+            backgroundScope = applicationCoroutineScope,
+            applicationContext = testableContext,
+            mediaControlChipInteractor = mediaControlChipInteractor,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelKosmos.kt
index 62cdc87..93502f3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/popups/ui/viewmodel/StatusBarPopupChipsViewModelKosmos.kt
@@ -18,6 +18,12 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.featurepods.media.ui.viewmodel.mediaControlChipViewModel
 
 val Kosmos.statusBarPopupChipsViewModel: StatusBarPopupChipsViewModel by
-    Kosmos.Fixture { StatusBarPopupChipsViewModel(testScope.backgroundScope) }
+    Kosmos.Fixture {
+        StatusBarPopupChipsViewModel(
+            testScope.backgroundScope,
+            mediaControlChipViewModel = mediaControlChipViewModel,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/headsup/AvalancheControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/headsup/AvalancheControllerKosmos.kt
new file mode 100644
index 0000000..2a2f5f9
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/headsup/AvalancheControllerKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 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.headsup
+
+import com.android.internal.logging.uiEventLoggerFake
+import com.android.systemui.dump.dumpManager
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.util.mockito.mock
+
+var Kosmos.mockAvalancheController by Fixture { mock<AvalancheController>() }
+
+val Kosmos.avalancheController by Fixture {
+    AvalancheController(dumpManager, uiEventLoggerFake, headsUpManagerLogger, bgHandler = mock())
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerKosmos.kt
index de9485d..dfc8a68 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerKosmos.kt
@@ -16,8 +16,44 @@
 
 package com.android.systemui.statusbar.notification.headsup
 
+import android.content.applicationContext
+import android.view.accessibility.accessibilityManagerWrapper
+import com.android.internal.logging.uiEventLoggerFake
+import com.android.systemui.concurrency.fakeExecutor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.plugins.statusbar.statusBarStateController
+import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider
+import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager
+import com.android.systemui.statusbar.phone.keyguardBypassController
+import com.android.systemui.statusbar.policy.configurationController
+import com.android.systemui.util.concurrency.mockExecutorHandler
+import com.android.systemui.util.kotlin.JavaAdapter
 import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.settings.fakeGlobalSettings
+import com.android.systemui.util.time.fakeSystemClock
 
-var Kosmos.headsUpManager by Fixture { mock<HeadsUpManager>() }
+var Kosmos.mockHeadsUpManager by Fixture { mock<HeadsUpManager>() }
+
+var Kosmos.headsUpManager: HeadsUpManager by Fixture {
+    HeadsUpManagerImpl(
+        applicationContext,
+        headsUpManagerLogger,
+        statusBarStateController,
+        keyguardBypassController,
+        mock<GroupMembershipManager>(),
+        visualStabilityProvider,
+        configurationController,
+        mockExecutorHandler(fakeExecutor),
+        fakeGlobalSettings,
+        fakeSystemClock,
+        fakeExecutor,
+        accessibilityManagerWrapper,
+        uiEventLoggerFake,
+        JavaAdapter(testScope.backgroundScope),
+        shadeInteractor,
+        avalancheController,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerLoggerKosmos.kt
new file mode 100644
index 0000000..d595fa6
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerLoggerKosmos.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 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.headsup
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.log.logcatLogBuffer
+import org.mockito.kotlin.mock
+
+val Kosmos.mockHeadsUpManagerLogger by Fixture { mock<HeadsUpManagerLogger>() }
+
+val Kosmos.headsUpManagerLogger by Fixture {
+    HeadsUpManagerLogger(logcatLogBuffer("HeadsUpManagerLogger"))
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/OnUserInteractionCallbackKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/OnUserInteractionCallbackKosmos.kt
index ec54c33..cc3f21b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/OnUserInteractionCallbackKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/OnUserInteractionCallbackKosmos.kt
@@ -22,14 +22,14 @@
 import com.android.systemui.statusbar.notification.collection.inflation.OnUserInteractionCallbackImpl
 import com.android.systemui.statusbar.notification.collection.notifCollection
 import com.android.systemui.statusbar.notification.collection.render.notificationVisibilityProvider
-import com.android.systemui.statusbar.notification.headsup.headsUpManager
+import com.android.systemui.statusbar.notification.headsup.mockHeadsUpManager
 
 var Kosmos.onUserInteractionCallback: OnUserInteractionCallback by
     Kosmos.Fixture {
         OnUserInteractionCallbackImpl(
             notificationVisibilityProvider,
             notifCollection,
-            headsUpManager,
+            mockHeadsUpManager,
             statusBarStateController,
             visualStabilityCoordinator,
         )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/AmbientStateKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/AmbientStateKosmos.kt
index 383e31d..65f4ec1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/AmbientStateKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/AmbientStateKosmos.kt
@@ -21,6 +21,7 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.shade.transition.largeScreenShadeInterpolator
+import com.android.systemui.statusbar.notification.headsup.mockAvalancheController
 import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
@@ -33,6 +34,6 @@
         /*bypassController=*/ stackScrollAlgorithmBypassController,
         /*statusBarKeyguardViewManager=*/ statusBarKeyguardViewManager,
         /*largeScreenShadeInterpolator=*/ largeScreenShadeInterpolator,
-        /*avalancheController=*/ avalancheController,
+        /*avalancheController=*/ mockAvalancheController,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmKosmos.kt
index a5c4bfd..67343c95 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmKosmos.kt
@@ -18,7 +18,6 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.statusbar.notification.headsup.AvalancheController
 import com.android.systemui.util.mockito.mock
 
 var Kosmos.stackScrollAlgorithmSectionProvider by Fixture {
@@ -28,5 +27,3 @@
 var Kosmos.stackScrollAlgorithmBypassController by Fixture {
     mock<StackScrollAlgorithm.BypassController>()
 }
-
-var Kosmos.avalancheController by Fixture { mock<AvalancheController>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt
index e972c2c..64f16da 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/WindowRootViewVisibilityInteractorKosmos.kt
@@ -25,14 +25,14 @@
 import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
-import com.android.systemui.statusbar.notification.headsup.headsUpManager
+import com.android.systemui.statusbar.notification.headsup.mockHeadsUpManager
 
 val Kosmos.windowRootViewVisibilityInteractor by Fixture {
     WindowRootViewVisibilityInteractor(
         scope = applicationCoroutineScope,
         windowRootViewVisibilityRepository = windowRootViewVisibilityRepository,
         keyguardRepository = keyguardRepository,
-        headsUpManager = headsUpManager,
+        headsUpManager = mockHeadsUpManager,
         powerInteractor = powerInteractor,
         activeNotificationsInteractor = activeNotificationsInteractor,
     ) {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/DozeServiceHostKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/DozeServiceHostKosmos.kt
index f86824a..d0bf584 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/DozeServiceHostKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/DozeServiceHostKosmos.kt
@@ -26,7 +26,7 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.plugins.statusbar.statusBarStateController
 import com.android.systemui.shade.domain.interactor.shadeLockscreenInteractor
-import com.android.systemui.statusbar.notification.headsup.headsUpManager
+import com.android.systemui.statusbar.notification.headsup.mockHeadsUpManager
 import com.android.systemui.statusbar.notificationShadeWindowController
 import com.android.systemui.statusbar.policy.batteryController
 import com.android.systemui.statusbar.policy.deviceProvisionedController
@@ -42,7 +42,7 @@
             wakefulnessLifecycle,
             statusBarStateController,
             deviceProvisionedController,
-            headsUpManager,
+            mockHeadsUpManager,
             batteryController,
             scrimController,
             { biometricUnlockController },
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerKosmos.kt
index 5b7f23b..9adaeff9 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ShadeTouchableRegionManagerKosmos.kt
@@ -24,7 +24,7 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
-import com.android.systemui.statusbar.notification.headsup.headsUpManager
+import com.android.systemui.statusbar.notification.headsup.mockHeadsUpManager
 import com.android.systemui.statusbar.notificationShadeWindowController
 import com.android.systemui.statusbar.policy.configurationController
 import com.android.systemui.util.kotlin.JavaAdapter
@@ -36,7 +36,7 @@
             applicationContext,
             notificationShadeWindowController,
             configurationController,
-            headsUpManager,
+            mockHeadsUpManager,
             shadeInteractor,
             { sceneInteractor },
             JavaAdapter(testScope.backgroundScope),
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterKosmos.kt
index 6083414..7743a1c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterKosmos.kt
@@ -36,7 +36,7 @@
 import com.android.systemui.statusbar.commandQueue
 import com.android.systemui.statusbar.notification.collection.provider.launchFullScreenIntentProvider
 import com.android.systemui.statusbar.notification.collection.render.notificationVisibilityProvider
-import com.android.systemui.statusbar.notification.headsup.headsUpManager
+import com.android.systemui.statusbar.notification.headsup.mockHeadsUpManager
 import com.android.systemui.statusbar.notification.notificationTransitionAnimatorControllerProvider
 import com.android.systemui.statusbar.notification.row.onUserInteractionCallback
 import com.android.systemui.statusbar.notificationClickNotifier
@@ -58,7 +58,7 @@
             fakeExecutorHandler,
             fakeExecutor,
             notificationVisibilityProvider,
-            headsUpManager,
+            mockHeadsUpManager,
             activityStarter,
             commandQueue,
             notificationClickNotifier,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
index 924b6b4..b38a723 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.statusbar.chips.ui.viewmodel.ongoingActivityChipsViewModel
 import com.android.systemui.statusbar.events.domain.interactor.systemStatusEventAnimationInteractor
+import com.android.systemui.statusbar.featurepods.popups.ui.viewmodel.statusBarPopupChipsViewModel
 import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
 import com.android.systemui.statusbar.phone.domain.interactor.darkIconInteractor
@@ -48,6 +49,7 @@
             sceneContainerOcclusionInteractor,
             shadeInteractor,
             ongoingActivityChipsViewModel,
+            statusBarPopupChipsViewModel,
             systemStatusEventAnimationInteractor,
             applicationCoroutineScope,
         )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeCastController.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeCastController.kt
index 2df0c7a5..da6b2ae 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeCastController.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeCastController.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.policy
 
+import android.media.projection.StopReason
 import java.io.PrintWriter
 
 class FakeCastController : CastController {
@@ -45,7 +46,7 @@
 
     override fun startCasting(device: CastDevice?) {}
 
-    override fun stopCasting(device: CastDevice?) {
+    override fun stopCasting(device: CastDevice?, @StopReason stopReason: Int) {
         lastStoppedDevice = device
     }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckerCastController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckerCastController.java
index 2249bc0..857dc85 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckerCastController.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckerCastController.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.utils.leaks;
 
+import android.media.projection.StopReason;
 import android.testing.LeakCheck;
 
 import com.android.systemui.statusbar.policy.CastController;
@@ -51,7 +52,7 @@
     }
 
     @Override
-    public void stopCasting(CastDevice device) {
+    public void stopCasting(CastDevice device, @StopReason int stopReason) {
 
     }
 
diff --git a/nfc/java/android/nfc/OemLogItems.aidl b/packages/SystemUI/tests/utils/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepositoryKosmos.kt
similarity index 76%
rename from nfc/java/android/nfc/OemLogItems.aidl
rename to packages/SystemUI/tests/utils/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepositoryKosmos.kt
index 3bcb445..7281e03 100644
--- a/nfc/java/android/nfc/OemLogItems.aidl
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/window/data/repository/WindowRootViewBlurRepositoryKosmos.kt
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
-package android.nfc;
+package com.android.systemui.window.data.repository
 
-parcelable OemLogItems;
\ No newline at end of file
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.windowRootViewBlurRepository by Kosmos.Fixture { WindowRootViewBlurRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractorKosmos.kt
new file mode 100644
index 0000000..ad30ea2
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/window/domain/interactor/WindowRootViewBlurInteractorKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 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.window.domain.interactor
+
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.window.data.repository.windowRootViewBlurRepository
+
+val Kosmos.windowRootViewBlurInteractor by
+    Kosmos.Fixture {
+        WindowRootViewBlurInteractor(
+            repository = windowRootViewBlurRepository,
+            keyguardInteractor = keyguardInteractor,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelKosmos.kt
new file mode 100644
index 0000000..864048d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelKosmos.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 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.window.ui.viewmodel
+
+import com.android.systemui.keyguard.ui.transitions.FakeBouncerTransition
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.window.domain.interactor.windowRootViewBlurInteractor
+import org.mockito.internal.util.collections.Sets
+
+val Kosmos.fakeBouncerTransitions by
+    Kosmos.Fixture<Set<FakeBouncerTransition>> {
+        Sets.newSet(FakeBouncerTransition(), FakeBouncerTransition())
+    }
+
+val Kosmos.windowRootViewModel by
+    Kosmos.Fixture { WindowRootViewModel(fakeBouncerTransitions, windowRootViewBlurInteractor) }
diff --git a/ravenwood/scripts/extract-last-soong-commands.py b/ravenwood/scripts/extract-last-soong-commands.py
index c08d4aa..0629b77 100755
--- a/ravenwood/scripts/extract-last-soong-commands.py
+++ b/ravenwood/scripts/extract-last-soong-commands.py
@@ -32,7 +32,7 @@
 HEADER = r'''#!/bin/bash
 
 set -e # Stop on a failed command
-
+set -x # Print command line before executing
 cd "${ANDROID_BUILD_TOP:?}"
 
 '''
@@ -65,16 +65,8 @@
                     command = m.groups()[0]
 
                     count += 1
-                    out.write(f'### Command {count} ========\n')
-
-                    # Show the full command line before executing it.
-                    out.write('#echo ' + shlex.quote(command) + '\n')
-                    out.write('\n')
-
-                    # Execute the command.
-                    out.write('#' + command + '\n')
-
-                    out.write('\n')
+                    out.write(f'### Command {count} ========\n\n')
+                    out.write('#' + command + '\n\n')
 
                     continue
 
diff --git a/ravenwood/texts/ravenwood-build.prop b/ravenwood/texts/ravenwood-build.prop
index 93a18cf..7cc4454 100644
--- a/ravenwood/texts/ravenwood-build.prop
+++ b/ravenwood/texts/ravenwood-build.prop
@@ -42,3 +42,4 @@
 ro.build.version.release_or_codename=$$$ro.build.version.release_or_codename
 ro.build.version.release_or_preview_display=$$$ro.build.version.release_or_preview_display
 ro.build.version.sdk=$$$ro.build.version.sdk
+ro.build.version.sdk_full=$$$ro.build.version.sdk_full
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 5133575..79888b0 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -261,27 +261,27 @@
                             ? event.getDisplayId() : Display.DEFAULT_DISPLAY;
 
                     switch (gestureType) {
-                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_IN:
+                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN:
                                 mAms.getMagnificationController().scaleMagnificationByStep(
                                         displayId, MagnificationController.ZOOM_DIRECTION_IN);
                             return true;
-                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_OUT:
+                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT:
                                 mAms.getMagnificationController().scaleMagnificationByStep(
                                         displayId, MagnificationController.ZOOM_DIRECTION_OUT);
                             return true;
-                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_LEFT:
+                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT:
                             mAms.getMagnificationController().panMagnificationByStep(
                                     displayId, MagnificationController.PAN_DIRECTION_LEFT);
                             return true;
-                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_RIGHT:
+                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT:
                             mAms.getMagnificationController().panMagnificationByStep(
                                     displayId, MagnificationController.PAN_DIRECTION_RIGHT);
                             return true;
-                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_UP:
+                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP:
                             mAms.getMagnificationController().panMagnificationByStep(
                                     displayId, MagnificationController.PAN_DIRECTION_UP);
                             return true;
-                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_DOWN:
+                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN:
                             mAms.getMagnificationController().panMagnificationByStep(
                                     displayId, MagnificationController.PAN_DIRECTION_DOWN);
                             return true;
@@ -292,12 +292,12 @@
                 @Override
                 public boolean isKeyGestureSupported(int gestureType) {
                     return switch (gestureType) {
-                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_IN,
-                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_OUT,
-                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_LEFT,
-                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_RIGHT,
-                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_UP,
-                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_DOWN -> true;
+                        case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN,
+                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT,
+                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT,
+                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT,
+                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP,
+                             KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN -> true;
                         default -> false;
                     };
                 }
diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java
index 669025f..37276dd 100644
--- a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java
@@ -155,23 +155,8 @@
         int callingPid = Binder.getCallingPid();
 
         final SafeOneTimeExecuteAppFunctionCallback safeExecuteAppFunctionCallback =
-                new SafeOneTimeExecuteAppFunctionCallback(executeAppFunctionCallback,
-                        new SafeOneTimeExecuteAppFunctionCallback.CompletionCallback() {
-                            @Override
-                            public void finalizeOnSuccess(
-                                    @NonNull ExecuteAppFunctionResponse result,
-                                    long executionStartTimeMillis) {
-                                mLoggerWrapper.logAppFunctionSuccess(requestInternal, result,
-                                        callingUid, executionStartTimeMillis);
-                            }
-
-                            @Override
-                            public void finalizeOnError(@NonNull AppFunctionException error,
-                                    long executionStartTimeMillis) {
-                                mLoggerWrapper.logAppFunctionError(requestInternal,
-                                        error.getErrorCode(), callingUid, executionStartTimeMillis);
-                            }
-                        });
+                initializeSafeExecuteAppFunctionCallback(
+                        requestInternal, executeAppFunctionCallback, callingUid);
 
         String validatedCallingPackage;
         try {
@@ -576,6 +561,38 @@
         }
     }
 
+    /**
+     * Returns a new {@link SafeOneTimeExecuteAppFunctionCallback} initialized with a {@link
+     * SafeOneTimeExecuteAppFunctionCallback.CompletionCallback} that logs the results.
+     */
+    @VisibleForTesting
+    SafeOneTimeExecuteAppFunctionCallback initializeSafeExecuteAppFunctionCallback(
+            @NonNull ExecuteAppFunctionAidlRequest requestInternal,
+            @NonNull IExecuteAppFunctionCallback executeAppFunctionCallback,
+            int callingUid) {
+        return new SafeOneTimeExecuteAppFunctionCallback(
+                executeAppFunctionCallback,
+                new SafeOneTimeExecuteAppFunctionCallback.CompletionCallback() {
+                    @Override
+                    public void finalizeOnSuccess(
+                            @NonNull ExecuteAppFunctionResponse result,
+                            long executionStartTimeMillis) {
+                        mLoggerWrapper.logAppFunctionSuccess(
+                                requestInternal, result, callingUid, executionStartTimeMillis);
+                    }
+
+                    @Override
+                    public void finalizeOnError(
+                            @NonNull AppFunctionException error, long executionStartTimeMillis) {
+                        mLoggerWrapper.logAppFunctionError(
+                                requestInternal,
+                                error.getErrorCode(),
+                                callingUid,
+                                executionStartTimeMillis);
+                    }
+                });
+    }
+
     private static class AppFunctionMetadataObserver implements ObserverCallback {
         @Nullable private final MetadataSyncAdapter mPerUserMetadataSyncAdapter;
 
diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionsLoggerWrapper.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionsLoggerWrapper.java
index 7ba1bbc..666d8fe 100644
--- a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionsLoggerWrapper.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionsLoggerWrapper.java
@@ -26,58 +26,99 @@
 import android.os.SystemClock;
 import android.util.Slog;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.util.Objects;
+import java.util.concurrent.Executor;
 
 /** Wraps AppFunctionsStatsLog. */
 public class AppFunctionsLoggerWrapper {
     private static final String TAG = AppFunctionsLoggerWrapper.class.getSimpleName();
 
-    private static final int SUCCESS_RESPONSE_CODE = -1;
+    @VisibleForTesting static final int SUCCESS_RESPONSE_CODE = -1;
 
-    private final Context mContext;
+    private final PackageManager mPackageManager;
+    private final Executor mLoggingExecutor;
+    private final AppFunctionsLoggerClock mLoggerClock;
 
-    public AppFunctionsLoggerWrapper(@NonNull Context context) {
-        mContext = Objects.requireNonNull(context);
+    AppFunctionsLoggerWrapper(@NonNull Context context) {
+        this(context.getPackageManager(), LOGGING_THREAD_EXECUTOR, SystemClock::elapsedRealtime);
     }
 
-    void logAppFunctionSuccess(ExecuteAppFunctionAidlRequest request,
-            ExecuteAppFunctionResponse response, int callingUid, long executionStartTimeMillis) {
-        logAppFunctionsRequestReported(request, SUCCESS_RESPONSE_CODE,
-                response.getResponseDataSize(), callingUid, executionStartTimeMillis);
+    @VisibleForTesting
+    AppFunctionsLoggerWrapper(
+            @NonNull PackageManager packageManager,
+            @NonNull Executor executor,
+            AppFunctionsLoggerClock loggerClock) {
+        mLoggingExecutor = Objects.requireNonNull(executor);
+        mPackageManager = Objects.requireNonNull(packageManager);
+        mLoggerClock = loggerClock;
     }
 
-    void logAppFunctionError(ExecuteAppFunctionAidlRequest request, int errorCode, int callingUid,
+    void logAppFunctionSuccess(
+            ExecuteAppFunctionAidlRequest request,
+            ExecuteAppFunctionResponse response,
+            int callingUid,
             long executionStartTimeMillis) {
-        logAppFunctionsRequestReported(request, errorCode, /* responseSizeBytes = */ 0, callingUid,
+        logAppFunctionsRequestReported(
+                request,
+                SUCCESS_RESPONSE_CODE,
+                response.getResponseDataSize(),
+                callingUid,
                 executionStartTimeMillis);
     }
 
-    private void logAppFunctionsRequestReported(ExecuteAppFunctionAidlRequest request,
-            int errorCode, int responseSizeBytes, int callingUid, long executionStartTimeMillis) {
+    void logAppFunctionError(
+            ExecuteAppFunctionAidlRequest request,
+            int errorCode,
+            int callingUid,
+            long executionStartTimeMillis) {
+        logAppFunctionsRequestReported(
+                request,
+                errorCode,
+                /* responseSizeBytes= */ 0,
+                callingUid,
+                executionStartTimeMillis);
+    }
+
+    private void logAppFunctionsRequestReported(
+            ExecuteAppFunctionAidlRequest request,
+            int errorCode,
+            int responseSizeBytes,
+            int callingUid,
+            long executionStartTimeMillis) {
         final long e2eRequestLatencyMillis =
-                SystemClock.elapsedRealtime() - request.getRequestTime();
+                mLoggerClock.getCurrentTimeMillis() - request.getRequestTime();
         final long requestOverheadMillis =
-                executionStartTimeMillis > 0 ? (executionStartTimeMillis - request.getRequestTime())
+                executionStartTimeMillis > 0
+                        ? (executionStartTimeMillis - request.getRequestTime())
                         : e2eRequestLatencyMillis;
-        LOGGING_THREAD_EXECUTOR.execute(() -> AppFunctionsStatsLog.write(
-                AppFunctionsStatsLog.APP_FUNCTIONS_REQUEST_REPORTED,
-                /* callerPackageUid= */ callingUid,
-                /* targetPackageUid= */
-                getPackageUid(request.getClientRequest().getTargetPackageName()),
-                /* errorCode= */ errorCode,
-                /* requestSizeBytes= */ request.getClientRequest().getRequestDataSize(),
-                /* responseSizeBytes= */  responseSizeBytes,
-                /* requestDurationMs= */ e2eRequestLatencyMillis,
-                /* requestOverheadMs= */ requestOverheadMillis)
-        );
+        mLoggingExecutor.execute(
+                () ->
+                        AppFunctionsStatsLog.write(
+                                AppFunctionsStatsLog.APP_FUNCTIONS_REQUEST_REPORTED,
+                                /* callerPackageUid= */ callingUid,
+                                /* targetPackageUid= */ getPackageUid(
+                                        request.getClientRequest().getTargetPackageName()),
+                                /* errorCode= */ errorCode,
+                                /* requestSizeBytes= */ request.getClientRequest()
+                                        .getRequestDataSize(),
+                                /* responseSizeBytes= */ responseSizeBytes,
+                                /* requestDurationMs= */ e2eRequestLatencyMillis,
+                                /* requestOverheadMs= */ requestOverheadMillis));
     }
 
     private int getPackageUid(String packageName) {
         try {
-            return mContext.getPackageManager().getPackageUid(packageName, 0);
+            return mPackageManager.getPackageUid(packageName, 0);
         } catch (PackageManager.NameNotFoundException e) {
             Slog.e(TAG, "Package uid not found for " + packageName);
         }
         return 0;
     }
+
+    /** Wraps a custom clock for easier testing. */
+    interface AppFunctionsLoggerClock {
+        long getCurrentTimeMillis();
+    }
 }
diff --git a/services/appfunctions/java/com/android/server/appfunctions/RunAppFunctionServiceCallback.java b/services/appfunctions/java/com/android/server/appfunctions/RunAppFunctionServiceCallback.java
index a5ae7e3..4cba8ec 100644
--- a/services/appfunctions/java/com/android/server/appfunctions/RunAppFunctionServiceCallback.java
+++ b/services/appfunctions/java/com/android/server/appfunctions/RunAppFunctionServiceCallback.java
@@ -23,6 +23,7 @@
 import android.app.appfunctions.ICancellationCallback;
 import android.app.appfunctions.IExecuteAppFunctionCallback;
 import android.app.appfunctions.SafeOneTimeExecuteAppFunctionCallback;
+import android.os.SystemClock;
 import android.util.Slog;
 
 import com.android.server.appfunctions.RemoteServiceCaller.RunServiceCallCallback;
@@ -52,7 +53,8 @@
             @NonNull IAppFunctionService service,
             @NonNull ServiceUsageCompleteListener serviceUsageCompleteListener) {
         try {
-            mSafeExecuteAppFunctionCallback.setExecutionStartTimeMillis();
+            mSafeExecuteAppFunctionCallback.setExecutionStartTimeAfterBindMillis(
+                    SystemClock.elapsedRealtime());
             service.executeAppFunction(
                     mRequestInternal.getClientRequest(),
                     mRequestInternal.getCallingPackage(),
@@ -73,8 +75,7 @@
         } catch (Exception e) {
             mSafeExecuteAppFunctionCallback.onError(
                     new AppFunctionException(
-                            AppFunctionException.ERROR_APP_UNKNOWN_ERROR,
-                            e.getMessage()));
+                            AppFunctionException.ERROR_APP_UNKNOWN_ERROR, e.getMessage()));
             serviceUsageCompleteListener.onCompleted();
         }
     }
@@ -83,7 +84,8 @@
     public void onFailedToConnect() {
         Slog.e(TAG, "Failed to connect to service");
         mSafeExecuteAppFunctionCallback.onError(
-                new AppFunctionException(AppFunctionException.ERROR_APP_UNKNOWN_ERROR,
+                new AppFunctionException(
+                        AppFunctionException.ERROR_APP_UNKNOWN_ERROR,
                         "Failed to connect to AppFunctionService"));
     }
 
diff --git a/services/backup/java/com/android/server/backup/BackupManagerConstants.java b/services/backup/java/com/android/server/backup/BackupManagerConstants.java
index 4bd987a..b753d01 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerConstants.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerConstants.java
@@ -72,6 +72,9 @@
     public static final String BACKUP_FINISHED_NOTIFICATION_RECEIVERS =
             "backup_finished_notification_receivers";
 
+    @VisibleForTesting
+    public static final String WAKELOCK_TIMEOUT_MILLIS = "wakelock_timeout_millis";
+
     // Hard coded default values.
     @VisibleForTesting
     public static final long DEFAULT_KEY_VALUE_BACKUP_INTERVAL_MILLISECONDS =
@@ -97,6 +100,9 @@
     @VisibleForTesting
     public static final String DEFAULT_BACKUP_FINISHED_NOTIFICATION_RECEIVERS = "";
 
+    @VisibleForTesting
+    public static final long DEFAULT_WAKELOCK_TIMEOUT_MILLIS = 30 * 60 * 1000; // 30 minutes
+
     // Backup manager constants.
     private long mKeyValueBackupIntervalMilliseconds;
     private long mKeyValueBackupFuzzMilliseconds;
@@ -106,6 +112,7 @@
     private boolean mFullBackupRequireCharging;
     private int mFullBackupRequiredNetworkType;
     private String[] mBackupFinishedNotificationReceivers;
+    private long mWakelockTimeoutMillis;
 
     public BackupManagerConstants(Handler handler, ContentResolver resolver) {
         super(handler, resolver, Settings.Secure.getUriFor(SETTING));
@@ -152,6 +159,8 @@
         } else {
             mBackupFinishedNotificationReceivers = backupFinishedNotificationReceivers.split(":");
         }
+        mWakelockTimeoutMillis = parser.getLong(WAKELOCK_TIMEOUT_MILLIS,
+                DEFAULT_WAKELOCK_TIMEOUT_MILLIS);
     }
 
     // The following are access methods for the individual parameters.
@@ -235,4 +244,9 @@
         }
         return mBackupFinishedNotificationReceivers;
     }
+
+    public synchronized long getWakelockTimeoutMillis() {
+        Slog.v(TAG, "wakelock timeout: " + mWakelockTimeoutMillis);
+        return mWakelockTimeoutMillis;
+    }
 }
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 549f8fa..ac1f50f 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -181,11 +181,14 @@
     public static class BackupWakeLock {
         private final PowerManager.WakeLock mPowerManagerWakeLock;
         private boolean mHasQuit = false;
-        private int mUserId;
+        private final int mUserId;
+        private final BackupManagerConstants mBackupManagerConstants;
 
-        public BackupWakeLock(PowerManager.WakeLock powerManagerWakeLock, int userId) {
+        public BackupWakeLock(PowerManager.WakeLock powerManagerWakeLock, int userId,
+                BackupManagerConstants backupManagerConstants) {
             mPowerManagerWakeLock = powerManagerWakeLock;
             mUserId = userId;
+            mBackupManagerConstants = backupManagerConstants;
         }
 
         /** Acquires the {@link PowerManager.WakeLock} if hasn't been quit. */
@@ -199,7 +202,9 @@
                                         + mPowerManagerWakeLock.getTag()));
                 return;
             }
-            mPowerManagerWakeLock.acquire();
+            // Set a timeout for the wakelock. Otherwise if we fail internally and never call
+            // release(), the device might stay awake and drain battery indefinitely.
+            mPowerManagerWakeLock.acquire(mBackupManagerConstants.getWakelockTimeoutMillis());
             Slog.v(
                     TAG,
                     addUserIdToLogMessage(
@@ -674,10 +679,8 @@
         mBackupPreferences = new UserBackupPreferences(mContext, mBaseStateDir);
 
         // Power management
-        mWakelock = new BackupWakeLock(
-                mPowerManager.newWakeLock(
-                        PowerManager.PARTIAL_WAKE_LOCK,
-                        "*backup*-" + userId + "-" + userBackupThread.getThreadId()), userId);
+        mWakelock = new BackupWakeLock(mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                "*backup*-" + userId + "-" + userBackupThread.getThreadId()), userId, mConstants);
 
         // Set up the various sorts of package tracking we do
         mFullBackupScheduleFile = new File(mBaseStateDir, "fb-schedule");
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index a1d621d..6bf60bf 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -301,14 +301,19 @@
             // if the secure window is shown on a non-secure virtual display.
             DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
             Display display = displayManager.getDisplay(displayId);
-            if ((display.getFlags() & Display.FLAG_SECURE) == 0) {
-                showToastWhereUidIsRunning(activityInfo.applicationInfo.uid,
-                        com.android.internal.R.string.vdm_secure_window,
-                        Toast.LENGTH_LONG, mContext.getMainLooper());
+            if (display != null) {
+                if ((display.getFlags() & Display.FLAG_SECURE) == 0) {
+                    showToastWhereUidIsRunning(activityInfo.applicationInfo.uid,
+                            com.android.internal.R.string.vdm_secure_window,
+                            Toast.LENGTH_LONG, mContext.getMainLooper());
 
-                Counter.logIncrementWithUid(
-                        "virtual_devices.value_secure_window_blocked_count",
-                        mAttributionSource.getUid());
+                    Counter.logIncrementWithUid(
+                            "virtual_devices.value_secure_window_blocked_count",
+                            mAttributionSource.getUid());
+                }
+            } else {
+                Slog.e(TAG, "Calling onSecureWindowShown on a non existent/connected display: "
+                        + displayId);
             }
         }
 
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index bedc130..c1c03ff 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -18,6 +18,7 @@
 
 import static android.service.quickaccesswallet.Flags.launchWalletOptionOnPowerDoubleTap;
 
+import static com.android.hardware.input.Flags.overridePowerKeyBehaviorInFocusedWindow;
 import static com.android.internal.R.integer.config_defaultMinEmergencyGestureTapDurationMillis;
 
 import android.app.ActivityManager;
@@ -232,7 +233,7 @@
     }
 
     @VisibleForTesting
-    GestureLauncherService(Context context, MetricsLogger metricsLogger,
+    public GestureLauncherService(Context context, MetricsLogger metricsLogger,
             QuickAccessWalletClient quickAccessWalletClient, UiEventLogger uiEventLogger) {
         super(context);
         mContext = context;
@@ -600,6 +601,45 @@
         return res;
     }
 
+    /**
+     * Processes a power key event in GestureLauncherService without performing an action. This
+     * method is called on every KEYCODE_POWER ACTION_DOWN event and ensures that, even if
+     * KEYCODE_POWER events are passed to and handled by the app, the GestureLauncherService still
+     * keeps track of all running KEYCODE_POWER events for its gesture detection and relevant
+     * actions.
+     */
+    public void processPowerKeyDown(KeyEvent event) {
+        if (mEmergencyGestureEnabled && mEmergencyGesturePowerButtonCooldownPeriodMs >= 0
+                && event.getEventTime() - mLastEmergencyGestureTriggered
+                < mEmergencyGesturePowerButtonCooldownPeriodMs) {
+            return;
+        }
+        if (event.isLongPress()) {
+            return;
+        }
+
+        final long powerTapInterval;
+
+        synchronized (this) {
+            powerTapInterval = event.getEventTime() - mLastPowerDown;
+            mLastPowerDown = event.getEventTime();
+            if (powerTapInterval >= POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS) {
+                // Tap too slow, reset consecutive tap counts.
+                mFirstPowerDown = event.getEventTime();
+                mPowerButtonConsecutiveTaps = 1;
+                mPowerButtonSlowConsecutiveTaps = 1;
+            } else if (powerTapInterval >= POWER_DOUBLE_TAP_MAX_TIME_MS) {
+                // Tap too slow for shortcuts
+                mFirstPowerDown = event.getEventTime();
+                mPowerButtonConsecutiveTaps = 1;
+                mPowerButtonSlowConsecutiveTaps++;
+            } else if (!overridePowerKeyBehaviorInFocusedWindow() || powerTapInterval > 0) {
+                // Fast consecutive tap
+                mPowerButtonConsecutiveTaps++;
+                mPowerButtonSlowConsecutiveTaps++;
+            }
+        }
+    }
 
     /**
      * Attempts to intercept power key down event by detecting certain gesture patterns
@@ -648,7 +688,7 @@
                 mFirstPowerDown  = event.getEventTime();
                 mPowerButtonConsecutiveTaps = 1;
                 mPowerButtonSlowConsecutiveTaps++;
-            } else {
+            } else if (powerTapInterval > 0) {
                 // Fast consecutive tap
                 mPowerButtonConsecutiveTaps++;
                 mPowerButtonSlowConsecutiveTaps++;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 50b6990..c9f06ac 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -10837,8 +10837,12 @@
                     opti++;
                 }
                 synchronized (this) {
+                    // TODO: b/361161826 - Always pass in the dumpAll and let
+                    // BroadcastController decide how to treat it.
+                    final boolean requestDumpAll = "filter".equals(dumpPackage)
+                            ? dumpAll : true;
                     mBroadcastController.dumpBroadcastsLocked(fd, pw, args, opti,
-                            /* dumpAll= */ true, dumpPackage);
+                            requestDumpAll, dumpPackage);
                 }
             } else if ("broadcast-stats".equals(cmd)) {
                 if (opti < args.length) {
diff --git a/services/core/java/com/android/server/am/BroadcastController.java b/services/core/java/com/android/server/am/BroadcastController.java
index aa06b7e..bfacfbb 100644
--- a/services/core/java/com/android/server/am/BroadcastController.java
+++ b/services/core/java/com/android/server/am/BroadcastController.java
@@ -47,6 +47,8 @@
 import static com.android.server.am.ActivityManagerService.UPDATE_TIME_PREFERENCE_MSG;
 import static com.android.server.am.ActivityManagerService.UPDATE_TIME_ZONE;
 import static com.android.server.am.ActivityManagerService.checkComponentPermission;
+import static com.android.server.am.BroadcastRecord.debugLog;
+import static com.android.server.am.BroadcastRecord.intentToString;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -1017,6 +1019,13 @@
                         android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS,
                         callingPid, callingUid, "recordResponseEventWhileInBackground");
             }
+
+            if (brOptions.isDebugLogEnabled()) {
+                if (!isShellOrRoot(callingUid)
+                        && (callerApp == null || !callerApp.hasActiveInstrumentation())) {
+                    brOptions.setDebugLogEnabled(false);
+                }
+            }
         }
 
         // Verify that protected broadcasts are only being sent by system code,
@@ -1622,6 +1631,10 @@
             }
         }
         while (ir < NR) {
+            // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
+            if (callerInstantApp) {
+                intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
+            }
             if (receivers == null) {
                 receivers = new ArrayList();
             }
@@ -1647,7 +1660,9 @@
                     callerAppProcessState, mService.mPlatformCompat);
             broadcastSentEventRecord.setBroadcastRecord(r);
 
-            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r);
+            if (DEBUG_BROADCAST || r.debugLog()) {
+                Slog.v(TAG_BROADCAST, "Enqueueing broadcast " + r);
+            }
             queue.enqueueBroadcastLocked(r);
         } else {
             // There was nobody interested in the broadcast, but we still want to record
@@ -1657,11 +1672,19 @@
                 // This was an implicit broadcast... let's record it for posterity.
                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
             }
+            if (DEBUG_BROADCAST || debugLog(brOptions)) {
+                Slog.v(TAG_BROADCAST, "Skipping broadcast " + intentToString(intent)
+                        + " due to no receivers");
+            }
         }
 
         return ActivityManager.BROADCAST_SUCCESS;
     }
 
+    private boolean isShellOrRoot(int uid) {
+        return uid == SHELL_UID || uid == ROOT_UID;
+    }
+
     @GuardedBy("mService")
     private void scheduleCanceledResultTo(ProcessRecord resultToApp, IIntentReceiver resultTo,
             Intent intent, int userId, BroadcastOptions options, int callingUid,
@@ -2178,6 +2201,8 @@
         boolean printedAnything = false;
         boolean onlyReceivers = false;
         int filteredUid = Process.INVALID_UID;
+        boolean onlyFilter = false;
+        String dumpIntentAction = null;
 
         if ("history".equals(dumpPackage)) {
             if (opti < args.length && "-s".equals(args[opti])) {
@@ -2185,8 +2210,7 @@
             }
             onlyHistory = true;
             dumpPackage = null;
-        }
-        if ("receivers".equals(dumpPackage)) {
+        } else if ("receivers".equals(dumpPackage)) {
             onlyReceivers = true;
             dumpPackage = null;
             if (opti + 2 <= args.length) {
@@ -2205,7 +2229,23 @@
                     }
                 }
             }
+        } else if ("filter".equals(dumpPackage)) {
+            onlyFilter = true;
+            dumpPackage = null;
+            if (opti + 2 <= args.length) {
+                if ("--action".equals(args[opti++])) {
+                    dumpIntentAction = args[opti++];
+                    if (dumpIntentAction == null) {
+                        pw.printf("Missing argument for --action option\n");
+                        return;
+                    }
+                } else {
+                    pw.printf("Unknown argument: %s\n", args[opti]);
+                    return;
+                }
+            }
         }
+
         if (DEBUG_BROADCAST) {
             Slogf.d(TAG_BROADCAST, "dumpBroadcastsLocked(): dumpPackage=%s, onlyHistory=%b, "
                             + "onlyReceivers=%b, filteredUid=%d", dumpPackage, onlyHistory,
@@ -2213,7 +2253,7 @@
         }
 
         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
-        if (!onlyHistory && dumpAll) {
+        if (!onlyHistory && !onlyFilter && dumpAll) {
             if (mRegisteredReceivers.size() > 0) {
                 boolean printed = false;
                 Iterator it = mRegisteredReceivers.values().iterator();
@@ -2257,14 +2297,14 @@
 
         if (!onlyReceivers) {
             needSep = mBroadcastQueue.dumpLocked(fd, pw, args, opti,
-                    dumpConstants, dumpHistory, dumpAll, dumpPackage, needSep);
+                    dumpConstants, dumpHistory, dumpAll, dumpPackage, dumpIntentAction, needSep);
             printedAnything |= needSep;
         }
 
         needSep = true;
 
         synchronized (mStickyBroadcasts) {
-            if (!onlyHistory && !onlyReceivers && mStickyBroadcasts != null
+            if (!onlyHistory && !onlyReceivers && !onlyFilter && mStickyBroadcasts != null
                     && dumpPackage == null) {
                 for (int user = 0; user < mStickyBroadcasts.size(); user++) {
                     if (needSep) {
@@ -2312,13 +2352,12 @@
             }
         }
 
-        if (!onlyHistory && !onlyReceivers && dumpAll) {
+        if (!onlyHistory && !onlyReceivers && !onlyFilter && dumpAll) {
             pw.println();
-            pw.println("  Queue " + mBroadcastQueue.toString() + ": "
+            pw.println("  Queue " + mBroadcastQueue + ": "
                     + mBroadcastQueue.describeStateLocked());
             pw.println("  mHandler:");
             mService.mHandler.dump(new PrintWriterPrinter(pw), "    ");
-            needSep = true;
             printedAnything = true;
         }
 
diff --git a/services/core/java/com/android/server/am/BroadcastHistory.java b/services/core/java/com/android/server/am/BroadcastHistory.java
index d6e3d43..6ddf60b 100644
--- a/services/core/java/com/android/server/am/BroadcastHistory.java
+++ b/services/core/java/com/android/server/am/BroadcastHistory.java
@@ -29,6 +29,7 @@
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.Objects;
 
 /**
  * Collection of recent historical broadcasts that are available to be dumped
@@ -163,10 +164,11 @@
 
     @NeverCompile
     public boolean dumpLocked(@NonNull PrintWriter pw, @Nullable String dumpPackage,
-            @NonNull String queueName, @NonNull SimpleDateFormat sdf,
-            boolean dumpAll, boolean needSep) {
-        dumpBroadcastList(pw, sdf, mFrozenBroadcasts, "Frozen");
-        dumpBroadcastList(pw, sdf, mPendingBroadcasts, "Pending");
+            @Nullable String dumpIntentAction, @NonNull String queueName,
+            @NonNull SimpleDateFormat sdf, boolean dumpAll) {
+        boolean needSep = true;
+        dumpBroadcastList(pw, sdf, mFrozenBroadcasts, dumpIntentAction, dumpAll, "Frozen");
+        dumpBroadcastList(pw, sdf, mPendingBroadcasts, dumpIntentAction, dumpAll, "Pending");
 
         int i;
         boolean printed = false;
@@ -187,6 +189,10 @@
             if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
                 continue;
             }
+            if (dumpIntentAction != null && !Objects.equals(dumpIntentAction,
+                    r.intent.getAction())) {
+                continue;
+            }
             if (!printed) {
                 if (needSep) {
                     pw.println();
@@ -195,9 +201,16 @@
                 pw.println("  Historical broadcasts [" + queueName + "]:");
                 printed = true;
             }
-            if (dumpAll) {
+            if (dumpIntentAction != null) {
                 pw.print("  Historical Broadcast " + queueName + " #");
-                        pw.print(i); pw.println(":");
+                pw.print(i); pw.println(":");
+                r.dump(pw, "    ", sdf);
+                if (!dumpAll) {
+                    break;
+                }
+            } else if (dumpAll) {
+                pw.print("  Historical Broadcast " + queueName + " #");
+                pw.print(i); pw.println(":");
                 r.dump(pw, "    ", sdf);
             } else {
                 pw.print("  #"); pw.print(i); pw.print(": "); pw.println(r);
@@ -213,7 +226,7 @@
             }
         } while (ringIndex != lastIndex);
 
-        if (dumpPackage == null) {
+        if (dumpPackage == null && dumpIntentAction == null) {
             lastIndex = ringIndex = mSummaryHistoryNext;
             if (dumpAll) {
                 printed = false;
@@ -276,15 +289,28 @@
     }
 
     private void dumpBroadcastList(@NonNull PrintWriter pw, @NonNull SimpleDateFormat sdf,
-            @NonNull ArrayList<BroadcastRecord> broadcasts, @NonNull String flavor) {
+            @NonNull ArrayList<BroadcastRecord> broadcasts, @Nullable String dumpIntentAction,
+            boolean dumpAll, @NonNull String flavor) {
         pw.print("  "); pw.print(flavor); pw.println(" broadcasts:");
         if (broadcasts.isEmpty()) {
             pw.println("    <empty>");
         } else {
+            boolean printedAnything = false;
             for (int idx = broadcasts.size() - 1; idx >= 0; --idx) {
                 final BroadcastRecord r = broadcasts.get(idx);
+                if (dumpIntentAction != null && !Objects.equals(dumpIntentAction,
+                        r.intent.getAction())) {
+                    continue;
+                }
                 pw.print(flavor); pw.print("  broadcast #"); pw.print(idx); pw.println(":");
                 r.dump(pw, "    ", sdf);
+                printedAnything = true;
+                if (dumpIntentAction != null && !dumpAll) {
+                    break;
+                }
+            }
+            if (!printedAnything) {
+                pw.println("    <no-matches>");
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 6386af6..a7d74a9 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -264,7 +264,8 @@
     @GuardedBy("mService")
     public abstract boolean dumpLocked(@NonNull FileDescriptor fd, @NonNull PrintWriter pw,
             @NonNull String[] args, int opti, boolean dumpConstants, boolean dumpHistory,
-            boolean dumpAll, @Nullable String dumpPackage, boolean needSep);
+            boolean dumpAll, @Nullable String dumpPackage, @Nullable String dumpIntentAction,
+            boolean needSep);
 
     /**
      * Execute {@link #dumpLocked} and store the output into
@@ -276,7 +277,7 @@
                     PrintWriter pw = new PrintWriter(out)) {
                 pw.print("Message: ");
                 pw.println(msg);
-                dumpLocked(fd, pw, null, 0, false, false, false, null, false);
+                dumpLocked(fd, pw, null, 0, false, false, false, null, null, false);
                 pw.flush();
             }
         }, DropBoxManager.IS_TEXT);
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index 9e4666c..b270513 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -798,7 +798,9 @@
             mService.mOomAdjuster.mCachedAppOptimizer.freezeAppAsyncImmediateLSP(r.callerApp);
             return;
         }
-        if (DEBUG_BROADCAST) logv("Enqueuing " + r + " for " + r.receivers.size() + " receivers");
+        if (DEBUG_BROADCAST || r.debugLog()) {
+            logv("Enqueuing " + r + " for " + r.receivers.size() + " receivers");
+        }
 
         final int cookie = traceBegin("enqueueBroadcast");
         r.applySingletonPolicy(mService);
@@ -1019,7 +1021,9 @@
                 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0;
 
         long startTimeNs = SystemClock.uptimeNanos();
-        if (DEBUG_BROADCAST) logv("Scheduling " + r + " to cold " + queue);
+        if (DEBUG_BROADCAST || r.debugLog()) {
+            logv("Scheduling " + r + " to cold " + queue);
+        }
         queue.app = mService.startProcessLocked(queue.processName, info, true, intentFlags,
                 hostingRecord, zygotePolicyFlags, allowWhileBooting, false);
         if (queue.app == null) {
@@ -1176,7 +1180,9 @@
             }
         }
 
-        if (DEBUG_BROADCAST) logv("Scheduling " + r + " to warm " + app);
+        if (DEBUG_BROADCAST || r.debugLog()) {
+            logv("Scheduling " + r + " to warm " + app);
+        }
         setDeliveryState(queue, app, r, index, receiver, BroadcastRecord.DELIVERY_SCHEDULED,
                 "scheduleReceiverWarmLocked");
 
@@ -1562,12 +1568,17 @@
         // bookkeeping to update for ordered broadcasts
         if (!isDeliveryStateTerminal(oldDeliveryState)
                 && isDeliveryStateTerminal(newDeliveryState)) {
-            if (DEBUG_BROADCAST
-                    && newDeliveryState != BroadcastRecord.DELIVERY_DELIVERED) {
-                logw("Delivery state of " + r + " to " + receiver
+            if ((DEBUG_BROADCAST && newDeliveryState != BroadcastRecord.DELIVERY_DELIVERED)
+                    || r.debugLog()) {
+                final String msg = "Delivery state of " + r + " to " + receiver
                         + " via " + app + " changed from "
                         + deliveryStateToString(oldDeliveryState) + " to "
-                        + deliveryStateToString(newDeliveryState) + " because " + reason);
+                        + deliveryStateToString(newDeliveryState) + " because " + reason;
+                if (newDeliveryState == BroadcastRecord.DELIVERY_DELIVERED) {
+                    logv(msg);
+                } else {
+                    logw(msg);
+                }
             }
 
             notifyFinishReceiver(queue, app, r, index, receiver);
@@ -2417,12 +2428,33 @@
     @GuardedBy("mService")
     public boolean dumpLocked(@NonNull FileDescriptor fd, @NonNull PrintWriter pw,
             @NonNull String[] args, int opti, boolean dumpConstants, boolean dumpHistory,
-            boolean dumpAll, @Nullable String dumpPackage, boolean needSep) {
+            boolean dumpAll, @Nullable String dumpPackage, @Nullable String dumpIntentAction,
+            boolean needSep) {
         final long now = SystemClock.uptimeMillis();
         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
         ipw.increaseIndent();
         ipw.println();
 
+        if (dumpIntentAction == null) {
+            dumpProcessQueues(ipw, now);
+            dumpBroadcastsWithIgnoredPolicies(ipw);
+            dumpForegroundUids(ipw);
+
+            if (dumpConstants) {
+                mFgConstants.dump(ipw);
+                mBgConstants.dump(ipw);
+            }
+        }
+
+        if (dumpHistory) {
+            final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+            needSep = mHistory.dumpLocked(ipw, dumpPackage, dumpIntentAction, mQueueName,
+                    sdf, dumpAll);
+        }
+        return needSep;
+    }
+
+    private void dumpProcessQueues(@NonNull IndentingPrintWriter ipw, @UptimeMillisLong long now) {
         ipw.println("📋 Per-process queues:");
         ipw.increaseIndent();
         for (int i = 0; i < mProcessQueues.size(); i++) {
@@ -2470,28 +2502,21 @@
         }
         ipw.decreaseIndent();
         ipw.println();
+    }
 
+    private void dumpBroadcastsWithIgnoredPolicies(@NonNull IndentingPrintWriter ipw) {
         ipw.println("Broadcasts with ignored delivery group policies:");
         ipw.increaseIndent();
         mService.dumpDeliveryGroupPolicyIgnoredActions(ipw);
         ipw.decreaseIndent();
         ipw.println();
+    }
 
+    private void dumpForegroundUids(@NonNull IndentingPrintWriter ipw) {
         ipw.println("Foreground UIDs:");
         ipw.increaseIndent();
         ipw.println(mUidForeground);
         ipw.decreaseIndent();
         ipw.println();
-
-        if (dumpConstants) {
-            mFgConstants.dump(ipw);
-            mBgConstants.dump(ipw);
-        }
-
-        if (dumpHistory) {
-            final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
-            needSep = mHistory.dumpLocked(ipw, dumpPackage, mQueueName, sdf, dumpAll, needSep);
-        }
-        return needSep;
     }
 }
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 8d0805d..c1b0a76 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -1285,31 +1285,43 @@
     }
 
     @Override
+    @NonNull
     public String toString() {
         if (mCachedToString == null) {
-            String label = intent.getAction();
-            if (label == null) {
-                label = intent.toString();
-            }
             mCachedToString = "BroadcastRecord{" + toShortString() + "}";
         }
         return mCachedToString;
     }
 
+    @NonNull
     public String toShortString() {
         if (mCachedToShortString == null) {
-            String label = intent.getAction();
-            if (label == null) {
-                label = intent.toString();
-            }
+            final String label = intentToString(intent);
             mCachedToShortString = Integer.toHexString(System.identityHashCode(this))
                     + " " + label + "/u" + userId;
         }
         return mCachedToShortString;
     }
 
+    @NonNull
+    public static String intentToString(@NonNull Intent intent) {
+        String label = intent.getAction();
+        if (label == null) {
+            label = intent.toString();
+        }
+        return label;
+    }
+
+    public boolean debugLog() {
+        return debugLog(options);
+    }
+
+    public static boolean debugLog(@Nullable BroadcastOptions options) {
+        return options != null && options.isDebugLogEnabled();
+    }
+
     @NeverCompile
-    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
+    public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
         long token = proto.start(fieldId);
         proto.write(BroadcastRecordProto.USER_ID, userId);
         proto.write(BroadcastRecordProto.INTENT_ACTION, intent.getAction());
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 49149e1..1503d88 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -1005,6 +1005,11 @@
     }
 
     @GuardedBy(anyOf = {"mService", "mProcLock"})
+    boolean hasActiveInstrumentation() {
+        return mInstr != null;
+    }
+
+    @GuardedBy(anyOf = {"mService", "mProcLock"})
     boolean isKilledByAm() {
         return mKilledByAm;
     }
diff --git a/services/core/java/com/android/server/display/BrightnessRangeController.java b/services/core/java/com/android/server/display/BrightnessRangeController.java
index 4fd9275..0f0c900 100644
--- a/services/core/java/com/android/server/display/BrightnessRangeController.java
+++ b/services/core/java/com/android/server/display/BrightnessRangeController.java
@@ -59,7 +59,7 @@
         mModeChangeCallback = modeChangeCallback;
         mHdrClamper = hdrClamper;
         mNormalBrightnessModeController = normalBrightnessModeController;
-        mUseHdrClamper = flags.isHdrClamperEnabled() && !flags.useNewHdrBrightnessModifier();
+        mUseHdrClamper = !flags.useNewHdrBrightnessModifier();
         mNormalBrightnessModeController.resetNbmData(
                 displayDeviceConfig.getLuxThrottlingData());
         if (flags.useNewHdrBrightnessModifier()) {
diff --git a/services/core/java/com/android/server/display/DisplayTopologyCoordinator.java b/services/core/java/com/android/server/display/DisplayTopologyCoordinator.java
index 461a9f3..8865039 100644
--- a/services/core/java/com/android/server/display/DisplayTopologyCoordinator.java
+++ b/services/core/java/com/android/server/display/DisplayTopologyCoordinator.java
@@ -16,8 +16,9 @@
 
 package com.android.server.display;
 
+import static android.hardware.display.DisplayTopology.pxToDp;
+
 import android.hardware.display.DisplayTopology;
-import android.util.DisplayMetrics;
 import android.view.Display;
 import android.view.DisplayInfo;
 
@@ -140,8 +141,7 @@
      * @return The width of the display in dp
      */
     private float getWidth(DisplayInfo info) {
-        return info.logicalWidth * (float) DisplayMetrics.DENSITY_DEFAULT
-                / info.logicalDensityDpi;
+        return pxToDp(info.logicalWidth, info.logicalDensityDpi);
     }
 
     /**
@@ -149,8 +149,7 @@
      * @return The height of the display in dp
      */
     private float getHeight(DisplayInfo info) {
-        return info.logicalHeight * (float) DisplayMetrics.DENSITY_DEFAULT
-                / info.logicalDensityDpi;
+        return pxToDp(info.logicalHeight, info.logicalDensityDpi);
     }
 
     private boolean isDisplayAllowedInTopology(DisplayInfo info) {
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index 85b6bbb..addfbf1 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -46,10 +46,6 @@
             Flags.FLAG_ENABLE_CONNECTED_DISPLAY_MANAGEMENT,
             Flags::enableConnectedDisplayManagement);
 
-    private final FlagState mHdrClamperFlagState = new FlagState(
-            Flags.FLAG_ENABLE_HDR_CLAMPER,
-            Flags::enableHdrClamper);
-
     private final FlagState mAdaptiveToneImprovements1 = new FlagState(
             Flags.FLAG_ENABLE_ADAPTIVE_TONE_IMPROVEMENTS_1,
             Flags::enableAdaptiveToneImprovements1);
@@ -278,11 +274,6 @@
         return mConnectedDisplayManagementFlagState.isEnabled();
     }
 
-    /** Returns whether hdr clamper is enabled on not. */
-    public boolean isHdrClamperEnabled() {
-        return mHdrClamperFlagState.isEnabled();
-    }
-
     /** Returns whether power throttling clamper is enabled on not. */
     public boolean isPowerThrottlingClamperEnabled() {
         return mPowerThrottlingClamperFlagState.isEnabled();
@@ -585,7 +576,6 @@
         pw.println(" " + mDisplayOffloadFlagState);
         pw.println(" " + mExternalDisplayLimitModeState);
         pw.println(" " + mDisplayTopology);
-        pw.println(" " + mHdrClamperFlagState);
         pw.println(" " + mPowerThrottlingClamperFlagState);
         pw.println(" " + mEvenDimmerFlagState);
         pw.println(" " + mSmallAreaDetectionFlagState);
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index 5f97410..eccbbb1 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -37,14 +37,6 @@
 }
 
 flag {
-    name: "enable_hdr_clamper"
-    namespace: "display_manager"
-    description: "Feature flag for HDR Clamper"
-    bug: "295100043"
-    is_fixed_read_only: true
-}
-
-flag {
     name: "enable_power_throttling_clamper"
     namespace: "display_manager"
     description: "Feature flag for Power Throttling Clamper"
diff --git a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
index 02e2882..1dd4a9b 100644
--- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
@@ -2080,10 +2080,13 @@
 
             restartObserver();
             mDeviceConfigDisplaySettings.startListening();
+            registerDisplayListener();
+        }
 
+        private void registerDisplayListener() {
             mInjector.registerDisplayListener(this, mHandler,
-                    DisplayManager.EVENT_FLAG_DISPLAY_CHANGED,
-                    DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS);
+                    DisplayManager.EVENT_TYPE_DISPLAY_CHANGED,
+                    DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS);
         }
 
         private void setLoggingEnabled(boolean loggingEnabled) {
@@ -2883,8 +2886,8 @@
             }
             mDisplayManagerInternal = mInjector.getDisplayManagerInternal();
             mInjector.registerDisplayListener(this, mHandler,
-                    DisplayManager.EVENT_FLAG_DISPLAY_REMOVED,
-                    DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS);
+                    DisplayManager.EVENT_TYPE_DISPLAY_REMOVED,
+                    DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS);
         }
 
         /**
diff --git a/services/core/java/com/android/server/display/mode/ProximitySensorObserver.java b/services/core/java/com/android/server/display/mode/ProximitySensorObserver.java
index 11418c1..0f78f0d 100644
--- a/services/core/java/com/android/server/display/mode/ProximitySensorObserver.java
+++ b/services/core/java/com/android/server/display/mode/ProximitySensorObserver.java
@@ -70,10 +70,14 @@
                 mDozeStateByDisplay.put(d.getDisplayId(), mInjector.isDozeState(d));
             }
         }
+        registerDisplayListener();
+    }
+
+    private void registerDisplayListener() {
         mInjector.registerDisplayListener(this, BackgroundThread.getHandler(),
-                DisplayManager.EVENT_FLAG_DISPLAY_ADDED
-                        | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
-                        | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED);
+                DisplayManager.EVENT_TYPE_DISPLAY_ADDED
+                        | DisplayManager.EVENT_TYPE_DISPLAY_CHANGED
+                        | DisplayManager.EVENT_TYPE_DISPLAY_REMOVED);
     }
 
     @GuardedBy("mSensorObserverLock")
diff --git a/services/core/java/com/android/server/display/mode/SkinThermalStatusObserver.java b/services/core/java/com/android/server/display/mode/SkinThermalStatusObserver.java
index 625b6bb..4ec9e83 100644
--- a/services/core/java/com/android/server/display/mode/SkinThermalStatusObserver.java
+++ b/services/core/java/com/android/server/display/mode/SkinThermalStatusObserver.java
@@ -83,14 +83,17 @@
         if (!mInjector.registerThermalServiceListener(this)) {
             return;
         }
-
-        mInjector.registerDisplayListener(this, mHandler,
-                DisplayManager.EVENT_FLAG_DISPLAY_ADDED | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
-                        | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED);
-
+        registerDisplayListener();
         populateInitialDisplayInfo();
     }
 
+    private void registerDisplayListener() {
+        mInjector.registerDisplayListener(this, mHandler,
+                DisplayManager.EVENT_TYPE_DISPLAY_ADDED
+                        | DisplayManager.EVENT_TYPE_DISPLAY_CHANGED
+                        | DisplayManager.EVENT_TYPE_DISPLAY_REMOVED);
+    }
+
     void setLoggingEnabled(boolean enabled) {
         mLoggingEnabled = enabled;
     }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index a8d5696..c384b54 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -1345,7 +1345,10 @@
             iter.remove();
         }
         if (mPendingActionClearedCallback != null) {
-            mPendingActionClearedCallback.onCleared(this);
+            PendingActionClearedCallback callback = mPendingActionClearedCallback;
+            // To prevent from calling the callback again during handling the callback itself.
+            mPendingActionClearedCallback = null;
+            callback.onCleared(this);
         }
     }
 
diff --git a/services/core/java/com/android/server/input/InputGestureManager.java b/services/core/java/com/android/server/input/InputGestureManager.java
index 8681ea5..9f785ac 100644
--- a/services/core/java/com/android/server/input/InputGestureManager.java
+++ b/services/core/java/com/android/server/input/InputGestureManager.java
@@ -173,7 +173,7 @@
                 ),
                 createKeyGesture(
                         KeyEvent.KEYCODE_DPAD_LEFT,
-                        KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
+                        KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON,
                         KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_LEFT
                 ),
                 createKeyGesture(
@@ -183,7 +183,7 @@
                 ),
                 createKeyGesture(
                         KeyEvent.KEYCODE_DPAD_RIGHT,
-                        KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
+                        KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON,
                         KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_RIGHT
                 ),
                 createKeyGesture(
@@ -217,22 +217,22 @@
                     KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK));
             systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_MINUS,
                     KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
-                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_OUT));
+                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT));
             systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_EQUALS,
                     KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
-                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_IN));
+                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN));
             systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_DPAD_LEFT,
-                    KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON,
-                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_LEFT));
+                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
+                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT));
             systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_DPAD_RIGHT,
-                    KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON,
-                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_RIGHT));
+                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
+                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT));
             systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_DPAD_UP,
-                    KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON,
-                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_UP));
+                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
+                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP));
             systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_DPAD_DOWN,
-                    KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON,
-                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_DOWN));
+                    KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
+                    KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN));
             systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_M,
                     KeyEvent.META_META_ON | KeyEvent.META_ALT_ON,
                     KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION));
diff --git a/services/core/java/com/android/server/inputmethod/IInputMethodManagerImpl.java b/services/core/java/com/android/server/inputmethod/IInputMethodManagerImpl.java
index e1f26d6..a8b61af 100644
--- a/services/core/java/com/android/server/inputmethod/IInputMethodManagerImpl.java
+++ b/services/core/java/com/android/server/inputmethod/IInputMethodManagerImpl.java
@@ -159,6 +159,9 @@
                 Manifest.permission.WRITE_SECURE_SETTINGS})
         void onImeSwitchButtonClickFromSystem(int displayId);
 
+        @PermissionVerified(Manifest.permission.TEST_INPUT_METHOD)
+        boolean shouldShowImeSwitcherButtonForTest();
+
         InputMethodSubtype getCurrentInputMethodSubtype(@UserIdInt int userId);
 
         void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes,
@@ -380,6 +383,14 @@
         mCallback.onImeSwitchButtonClickFromSystem(displayId);
     }
 
+    @EnforcePermission(Manifest.permission.TEST_INPUT_METHOD)
+    @Override
+    public boolean shouldShowImeSwitcherButtonForTest() {
+        super.shouldShowImeSwitcherButtonForTest_enforcePermission();
+
+        return mCallback.shouldShowImeSwitcherButtonForTest();
+    }
+
     @Override
     public InputMethodSubtype getCurrentInputMethodSubtype(@UserIdInt int userId) {
         return mCallback.getCurrentInputMethodSubtype(userId);
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index c653dec..1f414ac 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -4129,6 +4129,20 @@
         }
     }
 
+    /**
+     * A test API for CTS to check whether the IME Switcher button should be shown when the IME
+     * is shown.
+     */
+    @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.TEST_INPUT_METHOD)
+    public boolean shouldShowImeSwitcherButtonForTest() {
+        final int callingUserId = UserHandle.getCallingUserId();
+        synchronized (ImfLock.class) {
+            final int userId = resolveImeUserIdLocked(callingUserId);
+            return shouldShowImeSwitcherLocked(
+                    InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE, userId);
+        }
+    }
+
     @NonNull
     private static IllegalArgumentException getExceptionForUnknownImeId(
             @Nullable String imeId) {
diff --git a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
index 49d4332..b863c96 100644
--- a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
+++ b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
@@ -302,6 +302,12 @@
         mInner.onImeSwitchButtonClickFromSystem(displayId);
     }
 
+    @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.TEST_INPUT_METHOD)
+    @Override
+    public boolean shouldShowImeSwitcherButtonForTest() {
+        return mInner.shouldShowImeSwitcherButtonForTest();
+    }
+
     @Override
     public InputMethodSubtype getCurrentInputMethodSubtype(int userId) {
         return mInner.getCurrentInputMethodSubtype(userId);
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java b/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java
index ff40eec..7b59d6f1 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubServiceUtil.java
@@ -482,10 +482,7 @@
     /* package */
     static Message createHalMessage(HubMessage message) {
         Message outMessage = new Message();
-        outMessage.flags =
-                message.getDeliveryParams().isResponseRequired()
-                        ? Message.FLAG_REQUIRES_DELIVERY_STATUS
-                        : 0;
+        outMessage.flags = message.isResponseRequired() ? Message.FLAG_REQUIRES_DELIVERY_STATUS : 0;
         outMessage.permissions = new String[0];
         outMessage.sequenceNumber = message.getMessageSequenceNumber();
         outMessage.type = message.getMessageType();
@@ -502,8 +499,9 @@
     /* package */
     static HubMessage createHubMessage(Message message) {
         boolean isReliable = (message.flags & Message.FLAG_REQUIRES_DELIVERY_STATUS) != 0;
-        return new HubMessage(
-                message.type, message.content, new HubMessage.DeliveryParams(isReliable));
+        return new HubMessage.Builder(message.type, message.content)
+                .setResponseRequired(isReliable)
+                .build();
     }
 
     /**
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 7375a68..f50e8aa 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3082,16 +3082,42 @@
 
     private void sendRegisteredOnlyBroadcast(Intent baseIntent) {
         int[] userIds = mUmInternal.getProfileIds(mAmi.getCurrentUserId(), true);
-        Intent intent = new Intent(baseIntent).addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-        for (int userId : userIds) {
-            getContext().sendBroadcastAsUser(intent, UserHandle.of(userId), null);
-        }
-        // explicitly send the broadcast to all DND packages, even if they aren't currently running
-        for (int userId : userIds) {
-            for (String pkg : mConditionProviders.getAllowedPackages(userId)) {
-                Intent pkgIntent = new Intent(baseIntent).setPackage(pkg).setFlags(
-                        Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-                getContext().sendBroadcastAsUser(pkgIntent, UserHandle.of(userId));
+        if (Flags.nmBinderPerfReduceZenBroadcasts()) {
+            for (int userId : userIds) {
+                Context userContext = getContext().createContextAsUser(UserHandle.of(userId), 0);
+                String[] dndPackages = mConditionProviders.getAllowedPackages(userId)
+                        .toArray(new String[0]);
+
+                // We send the broadcast to all DND packages in the second step, so leave them out
+                // of this first broadcast for *running* receivers. That ensures each package only
+                // receives it once.
+                Intent registeredOnlyIntent = new Intent(baseIntent)
+                        .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                userContext.sendBroadcastMultiplePermissions(registeredOnlyIntent,
+                        /* receiverPermissions= */ new String[0],
+                        /* excludedPermissions= */ new String[0],
+                        /* excludedPackages= */ dndPackages);
+
+                for (String pkg : dndPackages) {
+                    Intent pkgIntent = new Intent(baseIntent).setPackage(pkg)
+                            .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+                    userContext.sendBroadcast(pkgIntent);
+                }
+            }
+        } else {
+            Intent intent = new Intent(baseIntent).addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+            for (int userId : userIds) {
+                getContext().sendBroadcastAsUser(intent, UserHandle.of(userId), null);
+            }
+
+            // explicitly send the broadcast to all DND packages, even if they aren't currently
+            // running
+            for (int userId : userIds) {
+                for (String pkg : mConditionProviders.getAllowedPackages(userId)) {
+                    Intent pkgIntent = new Intent(baseIntent).setPackage(pkg).setFlags(
+                            Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+                    getContext().sendBroadcastAsUser(pkgIntent, UserHandle.of(userId));
+                }
             }
         }
     }
@@ -4276,16 +4302,16 @@
 
         @Override
         @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
-        public @NonNull String[] getTypeAdjustmentDeniedPackages() {
+        public @NonNull int[] getAllowedAdjustmentKeyTypesForPackage(String pkg) {
             checkCallerIsSystemOrSystemUiOrShell();
-            return mAssistants.getTypeAdjustmentDeniedPackages();
+            return mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg);
         }
 
-        @Override
         @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
-        public void setTypeAdjustmentForPackageState(String pkg, boolean enabled) {
+        public void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, int type,
+                                                                 boolean enabled) {
             checkCallerIsSystemOrSystemUiOrShell();
-            mAssistants.setTypeAdjustmentForPackageState(pkg, enabled);
+            mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, type, enabled);
 
             handleSavePolicyFile();
         }
@@ -7083,7 +7109,7 @@
                         toRemove.add(potentialKey);
                     } else if (notificationClassificationUi()
                             && !mAssistants.isTypeAdjustmentAllowedForPackage(
-                            r.getSbn().getPackageName())) {
+                            r.getSbn().getPackageName(), adjustments.getInt(KEY_TYPE))) {
                         toRemove.add(potentialKey);
                     }
                 }
@@ -11740,7 +11766,11 @@
         private static final String ATT_DENIED = "denied_adjustments";
         private static final String ATT_ENABLED_TYPES = "enabled_key_types";
         private static final String ATT_NAS_UNSUPPORTED = "unsupported_adjustments";
-        private static final String ATT_TYPES_DENIED_APPS = "types_denied_apps";
+        // Encapsulates a list of packages and the bundle types enabled for each package.
+        private static final String TAG_TYPES_ENABLED_FOR_APPS = "types_enabled_for_apps";
+        // Encapsulates the bundle types enabled for a package.
+        private static final String ATT_APP_ENABLED_TYPES = "app_enabled_types";
+        private static final String ATT_PACKAGE = "package";
 
         private final Object mLock = new Object();
 
@@ -11756,8 +11786,14 @@
         @GuardedBy("mLock")
         private Map<Integer, HashSet<String>> mNasUnsupported = new ArrayMap<>();
 
+        // Types of classifications (aka bundles) enabled/allowed for this package.
+        // If the set is NULL (or package is not in the list), default classification allow list
+        // (the global one) should be used.
+        // If the set is empty, that indicates the package explicitly has all classifications
+        // disallowed.
         @GuardedBy("mLock")
-        private Set<String> mClassificationTypeDeniedPackages = new ArraySet<>();
+        private Map<String, Set<Integer>> mClassificationTypePackagesEnabledTypes =
+                new ArrayMap<>();
 
         protected ComponentName mDefaultFromConfig = null;
 
@@ -11958,41 +11994,88 @@
             }
         }
 
+        /**
+         * Returns whether the type adjustment is allowed for this particular package.
+         * If no package-specific restrictions have been set, defaults to the same value as
+         * isAdjustmentKeyTypeAllowed(type).
+         */
         @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
-        protected @NonNull boolean isTypeAdjustmentAllowedForPackage(String pkg) {
+        protected boolean isTypeAdjustmentAllowedForPackage(String pkg,
+                                                                     @Adjustment.Types int type) {
             synchronized (mLock) {
                 if (notificationClassificationUi()) {
-                    return !mClassificationTypeDeniedPackages.contains(pkg);
+                    if (mClassificationTypePackagesEnabledTypes.containsKey(pkg)) {
+                        Set<Integer> enabled = mClassificationTypePackagesEnabledTypes.get(pkg);
+                        if (enabled != null) {
+                            return enabled.contains(type);
+                        }
+                    }
+                    // If mClassificationTypePackagesEnabledTypes does not contain the pkg, or
+                    // the stored set is null, return the default.
+                    return isAdjustmentKeyTypeAllowed(type);
                 }
             }
-            return true;
+            return false;
         }
 
         @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
-        protected @NonNull String[] getTypeAdjustmentDeniedPackages() {
+        protected @NonNull int[] getAllowedAdjustmentKeyTypesForPackage(String pkg) {
             synchronized (mLock) {
                 if (notificationClassificationUi()) {
-                    return mClassificationTypeDeniedPackages.toArray(new String[0]);
+                    if (mClassificationTypePackagesEnabledTypes.containsKey(pkg)) {
+                        Set<Integer> enabled = mClassificationTypePackagesEnabledTypes.get(pkg);
+                        if (enabled != null) {
+                            // Convert Set to int[] for return.
+                            int[] returnEnabled = new int[enabled.size()];
+                            int i = 0;
+                            for (int val: enabled) {
+                                returnEnabled[i] = val;
+                                i++;
+                            }
+                            return returnEnabled;
+                        }
+                    }
+                    // If package is not in the map, or the value is null, return the default.
+                    return getAllowedAdjustmentKeyTypes();
                 }
             }
-            return new String[]{};
+            return new int[]{};
         }
 
         /**
          * Set whether a particular package can have its notification channels adjusted to have a
          * different type by NotificationAssistants.
+         * Note: once this method is called to enable or disable a specific type for a package,
+         * the global default is set as the starting point, and the type is enabled/disabled from
+         * there. Future changes to the global default will not apply automatically to this package.
          */
         @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
-        public void setTypeAdjustmentForPackageState(String pkg, boolean enabled) {
+        public void setAssistantAdjustmentKeyTypeStateForPackage(String pkg,
+                                                       @Adjustment.Types int type,
+                                                       boolean enabled) {
             if (!notificationClassificationUi()) {
                 return;
             }
             synchronized (mLock) {
-                if (enabled) {
-                    mClassificationTypeDeniedPackages.remove(pkg);
-                } else {
-                    mClassificationTypeDeniedPackages.add(pkg);
+                Set<Integer> enabledTypes = null;
+                if (mClassificationTypePackagesEnabledTypes.containsKey(pkg)) {
+                    enabledTypes = mClassificationTypePackagesEnabledTypes.get(pkg);
                 }
+                if (enabledTypes == null) {
+                    // Use global default to start.
+                    enabledTypes = new ArraySet<Integer>();
+                    // Convert from int[] to Set<Integer>
+                    for (int value : getAllowedAdjustmentKeyTypes()) {
+                        enabledTypes.add(value);
+                    }
+                }
+
+                if (enabled) {
+                    enabledTypes.add(type);
+                } else {
+                    enabledTypes.remove(type);
+                }
+                mClassificationTypePackagesEnabledTypes.put(pkg, enabledTypes);
             }
         }
 
@@ -12459,16 +12542,25 @@
                         TextUtils.join(",", mAllowedAdjustmentKeyTypes));
                 out.endTag(null, ATT_ENABLED_TYPES);
                 if (notificationClassificationUi()) {
-                    out.startTag(null, ATT_TYPES_DENIED_APPS);
-                    out.attribute(null, ATT_TYPES,
-                            TextUtils.join(",", mClassificationTypeDeniedPackages));
-                    out.endTag(null, ATT_TYPES_DENIED_APPS);
+                    out.startTag(null, TAG_TYPES_ENABLED_FOR_APPS);
+                    for (String pkg: mClassificationTypePackagesEnabledTypes.keySet()) {
+                        Set<Integer> allowedTypes =
+                                mClassificationTypePackagesEnabledTypes.get(pkg);
+                        if (allowedTypes != null) {
+                            out.startTag(null, ATT_APP_ENABLED_TYPES);
+                            out.attribute(null, ATT_PACKAGE, pkg);
+                            out.attribute(null, ATT_TYPES, TextUtils.join(",", allowedTypes));
+                            out.endTag(null, ATT_APP_ENABLED_TYPES);
+                        }
+                    }
+                    out.endTag(null, TAG_TYPES_ENABLED_FOR_APPS);
                 }
             }
         }
 
         @Override
-        protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException {
+        protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException,
+                XmlPullParserException {
             if (!notificationClassification()) {
                 return;
             }
@@ -12495,12 +12587,25 @@
                         }
                     }
                 }
-            } else if (notificationClassificationUi() && ATT_TYPES_DENIED_APPS.equals(tag)) {
-                final String apps = XmlUtils.readStringAttribute(parser, ATT_TYPES);
+            } else if (TAG_TYPES_ENABLED_FOR_APPS.equals(tag)) {
+                final int appsOuterDepth = parser.getDepth();
                 synchronized (mLock) {
-                    mClassificationTypeDeniedPackages.clear();
-                    if (!TextUtils.isEmpty(apps)) {
-                        mClassificationTypeDeniedPackages.addAll(Arrays.asList(apps.split(",")));
+                    mClassificationTypePackagesEnabledTypes.clear();
+                    while (XmlUtils.nextElementWithin(parser, appsOuterDepth)) {
+                        if (!ATT_APP_ENABLED_TYPES.equals(parser.getName())) {
+                            continue;
+                        }
+                        final String app = XmlUtils.readStringAttribute(parser, ATT_PACKAGE);
+                        Set<Integer> allowedTypes = new ArraySet<>();
+                        final String typesString = XmlUtils.readStringAttribute(parser, ATT_TYPES);
+                        if (!TextUtils.isEmpty(typesString)) {
+                            allowedTypes = Arrays.stream(typesString.split(","))
+                                    .map(Integer::valueOf)
+                                    .collect(Collectors.toSet());
+                        }
+                        // Empty type list is allowed, because empty type list signifies the user
+                        // has manually cleared the package of allowed types.
+                        mClassificationTypePackagesEnabledTypes.put(app, allowedTypes);
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig
index 65a38ae..f15c23e 100644
--- a/services/core/java/com/android/server/notification/flags.aconfig
+++ b/services/core/java/com/android/server/notification/flags.aconfig
@@ -187,3 +187,13 @@
   description: "Enables sound uri with vibration source in notification channel"
   bug: "351975435"
 }
+
+flag {
+  name: "nm_binder_perf_reduce_zen_broadcasts"
+  namespace: "systemui"
+  description: "Don't send duplicate zen-related (policy changed, etc) broadcasts"
+  bug: "324376849"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/pm/BroadcastHelper.java b/services/core/java/com/android/server/pm/BroadcastHelper.java
index 676c6fa..3660607 100644
--- a/services/core/java/com/android/server/pm/BroadcastHelper.java
+++ b/services/core/java/com/android/server/pm/BroadcastHelper.java
@@ -360,13 +360,17 @@
             @Nullable SparseArray<int[]> broadcastAllowList,
             @NonNull AndroidPackage pkg,
             @NonNull String[] sharedUidPackages,
-            @NonNull String reasonForTrace) {
+            @NonNull String reasonForTrace,
+            int callingUidForTrace) {
         final boolean isForWholeApp = componentNames.contains(packageName);
+        final String callingPackageNameForTrace = mContext.getPackageManager().getNameForUid(
+                callingUidForTrace);
         if (isForWholeApp || !android.content.pm.Flags.reduceBroadcastsForComponentStateChanges()) {
             tracePackageChangedBroadcastEvent(
                     android.content.pm.Flags.reduceBroadcastsForComponentStateChanges(),
                     reasonForTrace, packageName, "<implicit>" /* targetPackageName */,
-                    "whole" /* targetComponent */, componentNames.size());
+                    "whole" /* targetComponent */, componentNames.size(),
+                    callingPackageNameForTrace);
             sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp, componentNames,
                     packageUid, reason, userIds, instantUserIds, broadcastAllowList,
                     null /* targetPackageName */, null /* requiredPermissions */);
@@ -390,7 +394,7 @@
             if (!TextUtils.equals(packageName, "android")) {
                 tracePackageChangedBroadcastEvent(true /* applyFlag */, reasonForTrace, packageName,
                         "android" /* targetPackageName */, "notExported" /* targetComponent */,
-                        notExportedComponentNames.size());
+                        notExportedComponentNames.size(), callingPackageNameForTrace);
                 sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
                         notExportedComponentNames, packageUid, reason, userIds, instantUserIds,
                         broadcastAllowList, "android" /* targetPackageName */,
@@ -401,7 +405,7 @@
             // Second, send the PACKAGE_CHANGED broadcast to the application itself.
             tracePackageChangedBroadcastEvent(true /* applyFlag */, reasonForTrace, packageName,
                     packageName /* targetPackageName */, "notExported" /* targetComponent */,
-                    notExportedComponentNames.size());
+                    notExportedComponentNames.size(), callingPackageNameForTrace);
             sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
                     notExportedComponentNames, packageUid, reason, userIds, instantUserIds,
                     broadcastAllowList, packageName /* targetPackageName */,
@@ -415,7 +419,7 @@
                 }
                 tracePackageChangedBroadcastEvent(true /* applyFlag */, reasonForTrace, packageName,
                         sharedPackage /* targetPackageName */, "notExported" /* targetComponent */,
-                        notExportedComponentNames.size());
+                        notExportedComponentNames.size(), callingPackageNameForTrace);
                 sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
                         notExportedComponentNames, packageUid, reason, userIds, instantUserIds,
                         broadcastAllowList, sharedPackage /* targetPackageName */,
@@ -427,7 +431,7 @@
         if (!exportedComponentNames.isEmpty()) {
             tracePackageChangedBroadcastEvent(true /* applyFlag */, reasonForTrace, packageName,
                     "<implicit>" /* targetPackageName */, "exported" /* targetComponent */,
-                    exportedComponentNames.size());
+                    exportedComponentNames.size(), callingPackageNameForTrace);
             sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
                     exportedComponentNames, packageUid, reason, userIds, instantUserIds,
                     broadcastAllowList, null /* targetPackageName */,
@@ -770,7 +774,8 @@
                             dontKillApp,
                             new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
                             pkg.getUid(), null /* reason */,
-                            "static_shared_library_changed" /* reasonForTrace */);
+                            "static_shared_library_changed" /* reasonForTrace */,
+                            Process.SYSTEM_UID);
                 }
             }
         }
@@ -962,7 +967,8 @@
                                      @NonNull ArrayList<String> componentNames,
                                      int packageUid,
                                      @NonNull String reason,
-                                     @NonNull String reasonForTrace) {
+                                     @NonNull String reasonForTrace,
+                                     int callingUidForTrace) {
         PackageStateInternal setting = snapshot.getPackageStateInternal(packageName,
                 Process.SYSTEM_UID);
         if (setting == null || setting.getPkg() == null) {
@@ -980,7 +986,7 @@
         mHandler.post(() -> sendPackageChangedBroadcastInternal(
                 packageName, dontKillApp, componentNames, packageUid, reason, userIds,
                 instantUserIds, broadcastAllowList, setting.getPkg(),
-                sharedUserPackages, reasonForTrace));
+                sharedUserPackages, reasonForTrace, callingUidForTrace));
         mPackageMonitorCallbackHelper.notifyPackageChanged(packageName, dontKillApp, componentNames,
                 packageUid, reason, userIds, instantUserIds, broadcastAllowList, mHandler);
     }
@@ -1277,7 +1283,7 @@
     private static void tracePackageChangedBroadcastEvent(boolean applyFlag,
             @NonNull String reasonForTrace, @Nullable String packageName,
             @Nullable String targetPackageName, @Nullable String targetComponent,
-            int componentSize) {
+            int componentSize, @Nullable String callingPackageNameForTrace) {
 
         if (!Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
             return;
@@ -1291,6 +1297,7 @@
         builder.append(",tpn="); builder.append(targetPackageName);
         builder.append(",tc="); builder.append(targetComponent);
         builder.append(",cs="); builder.append(componentSize);
+        builder.append(",cpnft="); builder.append(callingPackageNameForTrace);
 
         Trace.instant(Trace.TRACE_TAG_SYSTEM_SERVER, builder.toString());
     }
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index b48b39c..85b92c7 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -2983,7 +2983,7 @@
         }
     }
 
-    public void sendPendingBroadcasts(String reasonForTrace) {
+    public void sendPendingBroadcasts(String reasonForTrace, int callingUidForTrace) {
         String[] packages;
         ArrayList<String>[] components;
         int numBroadcasts = 0, numUsers;
@@ -3028,7 +3028,7 @@
         for (int i = 0; i < numBroadcasts; i++) {
             mBroadcastHelper.sendPackageChangedBroadcast(snapshot, packages[i],
                     true /* dontKillApp */, components[i], uids[i], null /* reason */,
-                    reasonForTrace);
+                    reasonForTrace, callingUidForTrace);
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 286333c..4c959fa 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -1087,16 +1087,10 @@
                 return null;
             }
 
-            final AndroidFuture<Intent[]> ret = new AndroidFuture<>();
-            Intent[] intents;
-            mShortcutServiceInternal.createShortcutIntentsAsync(getCallingUserId(),
-                    callingPackage, packageName, shortcutId, user.getIdentifier(),
-                    injectBinderCallingPid(), injectBinderCallingUid(), ret);
-            try {
-                intents = ret.get();
-            } catch (InterruptedException | ExecutionException e) {
-                return null;
-            }
+            Intent[] intents = mShortcutServiceInternal.createShortcutIntents(
+                    getCallingUserId(), callingPackage, packageName, shortcutId,
+                    user.getIdentifier(), injectBinderCallingPid(),
+                    injectBinderCallingUid());
             if (intents == null || intents.length == 0) {
                 return null;
             }
@@ -1275,40 +1269,6 @@
         }
 
         @Override
-        public void getShortcutsAsync(@NonNull final String callingPackage,
-                @NonNull final ShortcutQueryWrapper query, @NonNull final UserHandle targetUser,
-                @NonNull final AndroidFuture<List<ShortcutInfo>> cb) {
-            ensureShortcutPermission(callingPackage);
-            if (!canAccessProfile(targetUser.getIdentifier(), "Cannot get shortcuts")) {
-                cb.complete(Collections.EMPTY_LIST);
-                return;
-            }
-
-            final long changedSince = query.getChangedSince();
-            final String packageName = query.getPackage();
-            final List<String> shortcutIds = query.getShortcutIds();
-            final List<LocusId> locusIds = query.getLocusIds();
-            final ComponentName componentName = query.getActivity();
-            final int flags = query.getQueryFlags();
-            if (shortcutIds != null && packageName == null) {
-                throw new IllegalArgumentException(
-                        "To query by shortcut ID, package name must also be set");
-            }
-            if (locusIds != null && packageName == null) {
-                throw new IllegalArgumentException(
-                        "To query by locus ID, package name must also be set");
-            }
-            if ((query.getQueryFlags() & ShortcutQuery.FLAG_GET_PERSONS_DATA) != 0) {
-                ensureStrictAccessShortcutsPermission(callingPackage);
-            }
-
-            mShortcutServiceInternal.getShortcutsAsync(getCallingUserId(),
-                    callingPackage, changedSince, packageName, shortcutIds, locusIds,
-                    componentName, flags, targetUser.getIdentifier(),
-                    injectBinderCallingPid(), injectBinderCallingUid(), cb);
-        }
-
-        @Override
         public void registerShortcutChangeCallback(@NonNull final String callingPackage,
                 @NonNull final ShortcutQueryWrapper query,
                 @NonNull final IShortcutChangeCallback callback) {
@@ -1406,15 +1366,8 @@
             if (!canAccessProfile(targetUserId, "Cannot access shortcuts")) {
                 return null;
             }
-
-            final AndroidFuture<ParcelFileDescriptor> ret = new AndroidFuture<>();
-            mShortcutServiceInternal.getShortcutIconFdAsync(getCallingUserId(),
-                    callingPackage, packageName, id, targetUserId, ret);
-            try {
-                return ret.get();
-            } catch (InterruptedException | ExecutionException e) {
-                throw new RuntimeException(e);
-            }
+            return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(),
+                    callingPackage, packageName, id, targetUserId);
         }
 
         @Override
@@ -1424,15 +1377,9 @@
             if (!canAccessProfile(userId, "Cannot access shortcuts")) {
                 return null;
             }
-
-            final AndroidFuture<String> ret = new AndroidFuture<>();
-            mShortcutServiceInternal.getShortcutIconUriAsync(getCallingUserId(), callingPackage,
-                    packageName, shortcutId, userId, ret);
-            try {
-                return ret.get();
-            } catch (InterruptedException | ExecutionException e) {
-                throw new RuntimeException(e);
-            }
+            return mShortcutServiceInternal.getShortcutIconUri(
+                    getCallingUserId(), callingPackage,
+                    packageName, shortcutId, userId);
         }
 
         @Override
@@ -1515,16 +1462,9 @@
                 ensureShortcutPermission(callerUid, callerPid, callingPackage);
             }
 
-            final AndroidFuture<Intent[]> ret = new AndroidFuture<>();
-            Intent[] intents;
-            mShortcutServiceInternal.createShortcutIntentsAsync(getCallingUserId(), callingPackage,
-                    packageName, shortcutId, targetUserId,
-                    injectBinderCallingPid(), injectBinderCallingUid(), ret);
-            try {
-                intents = ret.get();
-            } catch (InterruptedException | ExecutionException e) {
-                return false;
-            }
+            Intent[] intents = mShortcutServiceInternal.createShortcutIntents(
+                    getCallingUserId(), callingPackage, packageName, shortcutId,
+                    targetUserId, injectBinderCallingPid(), injectBinderCallingUid());
             if (intents == null || intents.length == 0) {
                 return false;
             }
diff --git a/services/core/java/com/android/server/pm/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java
index 0a06704..bc03b10b 100644
--- a/services/core/java/com/android/server/pm/PackageHandler.java
+++ b/services/core/java/com/android/server/pm/PackageHandler.java
@@ -76,7 +76,7 @@
     void doHandleMessage(Message msg) {
         switch (msg.what) {
             case SEND_PENDING_BROADCAST: {
-                mPm.sendPendingBroadcasts((String) msg.obj);
+                mPm.sendPendingBroadcasts((String) msg.obj, msg.arg1);
                 break;
             }
             case POST_INSTALL: {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a0bbc45..aaa4fdf 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3503,7 +3503,8 @@
      * if the resetEnabledSettingsOnAppDataCleared is {@code true}.
      */
     @GuardedBy("mLock")
-    private void resetComponentEnabledSettingsIfNeededLPw(String packageName, int userId) {
+    private void resetComponentEnabledSettingsIfNeededLPw(String packageName, int userId,
+            int callingUid) {
         final AndroidPackage pkg = packageName != null ? mPackages.get(packageName) : null;
         if (pkg == null || !pkg.isResetEnabledSettingsOnAppDataCleared()) {
             return;
@@ -3542,9 +3543,8 @@
         mPendingBroadcasts.addComponents(userId, packageName, updatedComponents);
         if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
             mHandler.sendMessageDelayed(
-                    mHandler.obtainMessage(SEND_PENDING_BROADCAST,
-                            "reset_component_state_changed" /* obj */),
-                    BROADCAST_DELAY);
+                    mHandler.obtainMessage(SEND_PENDING_BROADCAST, callingUid, 0 /* arg2 */,
+                            "reset_component_state_changed" /* obj */), BROADCAST_DELAY);
         }
     }
 
@@ -3841,8 +3841,9 @@
         mPendingBroadcasts.addComponent(userId, componentPkgName, componentName.getClassName());
 
         if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
-            mHandler.sendMessageDelayed(mHandler.obtainMessage(SEND_PENDING_BROADCAST,
-                    "component_label_icon_changed" /* obj */), BROADCAST_DELAY);
+            mHandler.sendMessageDelayed(
+                    mHandler.obtainMessage(SEND_PENDING_BROADCAST, callingUid, 0 /* arg2 */,
+                            "component_label_icon_changed" /* obj */), BROADCAST_DELAY);
         }
     }
 
@@ -4101,8 +4102,10 @@
                     final long broadcastDelay = SystemClock.uptimeMillis() > mServiceStartWithDelay
                             ? BROADCAST_DELAY
                             : BROADCAST_DELAY_DURING_STARTUP;
-                    mHandler.sendMessageDelayed(mHandler.obtainMessage(SEND_PENDING_BROADCAST,
-                            "component_state_changed" /* obj */), broadcastDelay);
+                    mHandler.sendMessageDelayed(
+                            mHandler.obtainMessage(SEND_PENDING_BROADCAST, callingUid,
+                                    0 /* arg2 */, "component_state_changed" /* obj */),
+                            broadcastDelay);
                 }
             }
         }
@@ -4121,7 +4124,7 @@
                         userId, pkgSettings.get(packageName).getAppId());
                 mBroadcastHelper.sendPackageChangedBroadcast(newSnapshot, packageName,
                         false /* dontKillApp */, components, packageUid, null /* reason */,
-                        "component_state_changed" /* reasonForTrace */);
+                        "component_state_changed" /* reasonForTrace */, callingUid);
             }
         } finally {
             Binder.restoreCallingIdentity(callingId);
@@ -4349,7 +4352,8 @@
                         true /* dontKillApp */,
                         new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
                         pkg.getUid(),
-                        Intent.ACTION_OVERLAY_CHANGED, "overlay_changed" /* reasonForTrace */);
+                        Intent.ACTION_OVERLAY_CHANGED, "overlay_changed" /* reasonForTrace */,
+                        Process.SYSTEM_UID);
             }
         }, overlayFilter);
 
@@ -4847,7 +4851,8 @@
                         mInstantAppRegistry.deleteInstantApplicationMetadata(packageName, userId);
                         synchronized (mLock) {
                             if (succeeded) {
-                                resetComponentEnabledSettingsIfNeededLPw(packageName, userId);
+                                resetComponentEnabledSettingsIfNeededLPw(packageName, userId,
+                                        callingUid);
                             }
                         }
                     }
@@ -6357,7 +6362,8 @@
         @Override
         public void setMimeGroup(String packageName, String mimeGroup, List<String> mimeTypes) {
             final Computer snapshot = snapshotComputer();
-            enforceOwnerRights(snapshot, packageName, Binder.getCallingUid());
+            final int callingUid = Binder.getCallingUid();
+            enforceOwnerRights(snapshot, packageName, callingUid);
             mimeTypes = CollectionUtils.emptyIfNull(mimeTypes);
             for (int i = 0; i < mimeTypes.size(); i++) {
                 if (mimeTypes.get(i).length() > 255) {
@@ -6401,7 +6407,7 @@
                             final int packageUid = UserHandle.getUid(userIds[i], appId);
                             mBroadcastHelper.sendPackageChangedBroadcast(snapShot, packageName,
                                     true /* dontKillApp */, components, packageUid, reason,
-                                    "mime_group_changed" /* reasonForTrace */);
+                                    "mime_group_changed" /* reasonForTrace */, callingUid);
                         }
                     }
                 });
@@ -8196,8 +8202,8 @@
         mRemovePackageHelper.cleanUpForMoveInstall(volumeUuid, packageName, fromCodePath);
     }
 
-    void sendPendingBroadcasts(String reasonForTrace) {
-        mInstallPackageHelper.sendPendingBroadcasts(reasonForTrace);
+    void sendPendingBroadcasts(String reasonForTrace, int callingUidForTrace) {
+        mInstallPackageHelper.sendPendingBroadcasts(reasonForTrace, callingUidForTrace);
     }
 
     void handlePackagePostInstall(@NonNull InstallRequest request, boolean launchedForRestore) {
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 6f50295..f140400 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -19,27 +19,11 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.Person;
-import android.app.appsearch.AppSearchBatchResult;
-import android.app.appsearch.AppSearchManager;
-import android.app.appsearch.AppSearchResult;
-import android.app.appsearch.AppSearchSession;
-import android.app.appsearch.BatchResultCallback;
-import android.app.appsearch.GenericDocument;
-import android.app.appsearch.GetByDocumentIdRequest;
-import android.app.appsearch.PutDocumentsRequest;
-import android.app.appsearch.RemoveByDocumentIdRequest;
-import android.app.appsearch.ReportUsageRequest;
-import android.app.appsearch.SearchResult;
-import android.app.appsearch.SearchResults;
-import android.app.appsearch.SearchSpec;
-import android.app.appsearch.SetSchemaRequest;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.LocusId;
-import android.content.pm.AppSearchShortcutInfo;
-import android.content.pm.AppSearchShortcutPerson;
 import android.content.pm.PackageInfo;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutManager;
@@ -58,7 +42,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.infra.AndroidFuture;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.CollectionUtils;
@@ -167,13 +150,6 @@
     private final ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>();
 
     /**
-     * A temporary copy of shortcuts that are to be cleared once persisted into AppSearch, keyed on
-     * IDs.
-     */
-    @GuardedBy("mPackageItemLock")
-    private final ArrayMap<String, ShortcutInfo> mTransientShortcuts = new ArrayMap<>(0);
-
-    /**
      * All the share targets from the package
      */
     @GuardedBy("mPackageItemLock")
@@ -196,9 +172,6 @@
     @GuardedBy("mPackageItemLock")
     private long mLastReportedTime;
 
-    @GuardedBy("mPackageItemLock")
-    private boolean mIsAppSearchSchemaUpToDate;
-
     private ShortcutPackage(ShortcutUser shortcutUser,
             int packageUserId, String packageName, ShortcutPackageInfo spi) {
         super(shortcutUser, packageUserId, packageName,
@@ -228,10 +201,6 @@
                 getPackageName(), getPackageUserId());
     }
 
-    private boolean isAppSearchEnabled() {
-        return mShortcutUser.mService.isAppSearchEnabled();
-    }
-
     public int getShortcutCount() {
         synchronized (mPackageItemLock) {
             return mShortcuts.size();
@@ -249,9 +218,6 @@
         // - Unshadow all shortcuts.
         // - Set disabled reason.
         // - Disable if needed.
-        final String query = String.format("%s:-%s AND %s:%s",
-                AppSearchShortcutInfo.KEY_FLAGS, ShortcutInfo.FLAG_SHADOW,
-                AppSearchShortcutInfo.KEY_DISABLED_REASON, restoreBlockReason);
         forEachShortcutMutate(si -> {
             if (restoreBlockReason == ShortcutInfo.DISABLED_REASON_NOT_DISABLED
                     && !si.hasFlags(ShortcutInfo.FLAG_SHADOW)
@@ -407,13 +373,7 @@
                     & (ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_CACHED_ALL));
         }
 
-        if (newShortcut.isExcludedFromSurfaces(ShortcutInfo.SURFACE_LAUNCHER)) {
-            if (isAppSearchEnabled()) {
-                synchronized (mPackageItemLock) {
-                    mTransientShortcuts.put(newShortcut.getId(), newShortcut);
-                }
-            }
-        } else {
+        if (!newShortcut.isExcludedFromSurfaces(ShortcutInfo.SURFACE_LAUNCHER)) {
             forceReplaceShortcutInner(newShortcut);
         }
         return oldShortcut != null;
@@ -466,8 +426,7 @@
                 }
 
                 changedShortcuts.add(shortcut);
-                deleted = deleteDynamicWithId(shortcut.getId(), /* ignoreInvisible =*/ true,
-                        /*ignorePersistedShortcuts=*/ true) != null;
+                deleted = deleteDynamicWithId(shortcut.getId(), /* ignoreInvisible =*/ true) != null;
             }
         }
         if (oldShortcut != null) {
@@ -480,25 +439,9 @@
                     & (ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_CACHED_ALL));
         }
 
-        if (newShortcut.isExcludedFromSurfaces(ShortcutInfo.SURFACE_LAUNCHER)) {
-            if (isAppSearchEnabled()) {
-                synchronized (mPackageItemLock) {
-                    mTransientShortcuts.put(newShortcut.getId(), newShortcut);
-                }
-            }
-        } else {
+        if (!newShortcut.isExcludedFromSurfaces(ShortcutInfo.SURFACE_LAUNCHER)) {
             forceReplaceShortcutInner(newShortcut);
         }
-        if (isAppSearchEnabled()) {
-            runAsSystem(() -> fromAppSearch().thenAccept(session ->
-                    session.reportUsage(new ReportUsageRequest.Builder(
-                            getPackageName(), newShortcut.getId()).build(), mExecutor, result -> {
-                                    if (!result.isSuccess()) {
-                                        Slog.e(TAG, "Failed to report usage via AppSearch. "
-                                                + result.getErrorMessage());
-                                    }
-                            })));
-        }
         return deleted;
     }
 
@@ -567,7 +510,6 @@
                 }
             }
         }
-        removeAllShortcutsAsync();
         if (changed) {
             return removeOrphans();
         }
@@ -581,11 +523,10 @@
      * @return The deleted shortcut, or null if it was not actually removed because it is either
      * pinned or cached.
      */
-    public ShortcutInfo deleteDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible,
-            boolean ignorePersistedShortcuts) {
+    public ShortcutInfo deleteDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible) {
         return deleteOrDisableWithId(
                 shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false, ignoreInvisible,
-                ShortcutInfo.DISABLED_REASON_NOT_DISABLED, ignorePersistedShortcuts);
+                ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
     }
 
     /**
@@ -596,9 +537,9 @@
      * it's still pinned.
      */
     private ShortcutInfo disableDynamicWithId(@NonNull String shortcutId, boolean ignoreInvisible,
-            int disabledReason, boolean ignorePersistedShortcuts) {
+            int disabledReason) {
         return deleteOrDisableWithId(shortcutId, /* disable =*/ true, /* overrideImmutable=*/ false,
-                ignoreInvisible, disabledReason, ignorePersistedShortcuts);
+                ignoreInvisible, disabledReason);
     }
 
     /**
@@ -614,7 +555,7 @@
         }
         return deleteOrDisableWithId(
                 shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false, ignoreInvisible,
-                ShortcutInfo.DISABLED_REASON_NOT_DISABLED, /*ignorePersistedShortcuts=*/ false);
+                ShortcutInfo.DISABLED_REASON_NOT_DISABLED);
     }
 
     /**
@@ -628,8 +569,7 @@
             int disabledMessageResId, boolean overrideImmutable, boolean ignoreInvisible,
             int disabledReason) {
         final ShortcutInfo deleted = deleteOrDisableWithId(shortcutId, /* disable =*/ true,
-                overrideImmutable, ignoreInvisible, disabledReason,
-                /*ignorePersistedShortcuts=*/ false);
+                overrideImmutable, ignoreInvisible, disabledReason);
 
         // If disabled id still exists, it is pinned and we need to update the disabled message.
         mutateShortcut(shortcutId, null, disabled -> {
@@ -648,8 +588,7 @@
 
     @Nullable
     private ShortcutInfo deleteOrDisableWithId(@NonNull String shortcutId, boolean disable,
-            boolean overrideImmutable, boolean ignoreInvisible, int disabledReason,
-            boolean ignorePersistedShortcuts) {
+            boolean overrideImmutable, boolean ignoreInvisible, int disabledReason) {
         Preconditions.checkState(
                 (disable == (disabledReason != ShortcutInfo.DISABLED_REASON_NOT_DISABLED)),
                 "disable and disabledReason disagree: " + disable + " vs " + disabledReason);
@@ -662,9 +601,6 @@
         if (!overrideImmutable) {
             ensureNotImmutable(oldShortcut, /*ignoreInvisible=*/ true);
         }
-        if (!ignorePersistedShortcuts) {
-            removeShortcutAsync(shortcutId);
-        }
         if (oldShortcut.isPinned() || oldShortcut.isCached()) {
             mutateShortcut(oldShortcut.getId(), oldShortcut, si -> {
                 si.setRank(0);
@@ -1214,8 +1150,7 @@
                                 "%s is no longer main activity. Disabling shorcut %s.",
                                 getPackageName(), si.getId()));
                         if (disableDynamicWithId(si.getId(), /*ignoreInvisible*/ false,
-                                ShortcutInfo.DISABLED_REASON_APP_CHANGED,
-                                /*ignorePersistedShortcuts*/ false) != null) {
+                                ShortcutInfo.DISABLED_REASON_APP_CHANGED) != null) {
                             return;
                         }
                         // Still pinned, so fall-through and possibly update the resources.
@@ -1367,8 +1302,7 @@
                     service.wtf("Found manifest shortcuts in excess list.");
                     continue;
                 }
-                deleteDynamicWithId(shortcut.getId(), /*ignoreInvisible=*/ true,
-                        /*ignorePersistedShortcuts=*/ true);
+                deleteDynamicWithId(shortcut.getId(), /*ignoreInvisible=*/ true);
             }
         }
 
@@ -1818,15 +1752,7 @@
     }
 
     private boolean hasNoShortcut() {
-        if (!isAppSearchEnabled()) {
-            return getShortcutCount() == 0;
-        }
-        final boolean[] hasAnyShortcut = new boolean[1];
-        forEachShortcutStopWhen(si -> {
-            hasAnyShortcut[0] = true;
-            return true;
-        });
-        return !hasAnyShortcut[0];
+        return getShortcutCount() == 0;
     }
 
     @Override
@@ -1845,10 +1771,6 @@
             ShortcutService.writeAttr(out, ATTR_NAME, getPackageName());
             ShortcutService.writeAttr(out, ATTR_CALL_COUNT, mApiCallCount);
             ShortcutService.writeAttr(out, ATTR_LAST_RESET, mLastResetTime);
-            if (!forBackup) {
-                ShortcutService.writeAttr(out, ATTR_SCHEMA_VERSON, mIsAppSearchSchemaUpToDate
-                        ? AppSearchShortcutInfo.SCHEMA_VERSION : 0);
-            }
             getPackageInfo().saveToXml(mShortcutUser.mService, out, forBackup);
 
             if (ShortcutService.DEBUG_REBOOT) {
@@ -2051,9 +1973,6 @@
         final ShortcutPackage ret = new ShortcutPackage(shortcutUser,
                 shortcutUser.getUserId(), packageName);
         synchronized (ret.mPackageItemLock) {
-            ret.mIsAppSearchSchemaUpToDate = ShortcutService.parseIntAttribute(
-                    parser, ATTR_SCHEMA_VERSON, 0) == AppSearchShortcutInfo.SCHEMA_VERSION;
-
             ret.mApiCallCount = ShortcutService.parseIntAttribute(parser, ATTR_CALL_COUNT);
             ret.mLastResetTime = ShortcutService.parseLongAttribute(parser, ATTR_LAST_RESET);
 
@@ -2478,47 +2397,6 @@
         }
     }
 
-    @NonNull
-    private AndroidFuture<AppSearchSession> setupSchema(
-            @NonNull final AppSearchSession session) {
-        if (ShortcutService.DEBUG_REBOOT) {
-            Slog.d(TAG, "Setup Schema for user=" + mShortcutUser.getUserId()
-                    + " pkg=" + getPackageName());
-        }
-        SetSchemaRequest.Builder schemaBuilder = new SetSchemaRequest.Builder()
-                .addSchemas(AppSearchShortcutPerson.SCHEMA, AppSearchShortcutInfo.SCHEMA)
-                .setForceOverride(true)
-                .addRequiredPermissionsForSchemaTypeVisibility(AppSearchShortcutInfo.SCHEMA_TYPE,
-                        Collections.singleton(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA))
-                .addRequiredPermissionsForSchemaTypeVisibility(AppSearchShortcutInfo.SCHEMA_TYPE,
-                        Collections.singleton(SetSchemaRequest.READ_ASSISTANT_APP_SEARCH_DATA))
-                .addRequiredPermissionsForSchemaTypeVisibility(AppSearchShortcutPerson.SCHEMA_TYPE,
-                        Collections.singleton(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA))
-                .addRequiredPermissionsForSchemaTypeVisibility(AppSearchShortcutPerson.SCHEMA_TYPE,
-                        Collections.singleton(SetSchemaRequest.READ_ASSISTANT_APP_SEARCH_DATA));
-        final AndroidFuture<AppSearchSession> future = new AndroidFuture<>();
-        session.setSchema(
-                schemaBuilder.build(), mExecutor, mShortcutUser.mExecutor, result -> {
-            if (!result.isSuccess()) {
-                future.completeExceptionally(
-                        new IllegalArgumentException(result.getErrorMessage()));
-                return;
-            }
-            future.complete(session);
-        });
-        return future;
-    }
-
-    @NonNull
-    private SearchSpec getSearchSpec() {
-        return new SearchSpec.Builder()
-                .addFilterSchemas(AppSearchShortcutInfo.SCHEMA_TYPE)
-                .addFilterNamespaces(getPackageName())
-                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
-                .setResultCountPerPage(mShortcutUser.mService.getMaxActivityShortcuts())
-                .build();
-    }
-
     private boolean verifyRanksSequential(List<ShortcutInfo> list) {
         boolean failed = false;
 
@@ -2533,186 +2411,6 @@
         return failed;
     }
 
-    // Async Operations
-
-    /**
-     * Removes all shortcuts from AppSearch.
-     */
-    void removeAllShortcutsAsync() {
-        if (!isAppSearchEnabled()) {
-            return;
-        }
-        runAsSystem(() -> fromAppSearch().thenAccept(session ->
-                session.remove("", getSearchSpec(), mShortcutUser.mExecutor, result -> {
-                    if (!result.isSuccess()) {
-                        Slog.e(TAG, "Failed to remove shortcuts from AppSearch. "
-                                + result.getErrorMessage());
-                    }
-                })));
-    }
-
-    void getShortcutByIdsAsync(@NonNull final Set<String> ids,
-            @NonNull final Consumer<List<ShortcutInfo>> cb) {
-        if (!isAppSearchEnabled()) {
-            cb.accept(Collections.emptyList());
-            return;
-        }
-        runAsSystem(() -> fromAppSearch().thenAccept(session -> {
-            session.getByDocumentId(new GetByDocumentIdRequest.Builder(getPackageName())
-                            .addIds(ids).build(), mShortcutUser.mExecutor,
-                    new BatchResultCallback<String, GenericDocument>() {
-                        @Override
-                        public void onResult(
-                                @NonNull AppSearchBatchResult<String, GenericDocument> result) {
-                            final List<ShortcutInfo> ret = result.getSuccesses().values()
-                                    .stream().map(doc ->
-                                            ShortcutInfo.createFromGenericDocument(
-                                                    mShortcutUser.getUserId(), doc))
-                                    .collect(Collectors.toList());
-                            cb.accept(ret);
-                        }
-                        @Override
-                        public void onSystemError(
-                                @Nullable Throwable throwable) {
-                            Slog.d(TAG, "Error retrieving shortcuts", throwable);
-                        }
-                    });
-        }));
-    }
-
-    private void removeShortcutAsync(@NonNull final String... id) {
-        Objects.requireNonNull(id);
-        removeShortcutAsync(Arrays.asList(id));
-    }
-
-    private void removeShortcutAsync(@NonNull final Collection<String> ids) {
-        if (!isAppSearchEnabled()) {
-            return;
-        }
-        runAsSystem(() -> fromAppSearch().thenAccept(session ->
-                session.remove(
-                        new RemoveByDocumentIdRequest.Builder(getPackageName()).addIds(ids).build(),
-                        mShortcutUser.mExecutor,
-                        new BatchResultCallback<String, Void>() {
-                            @Override
-                            public void onResult(
-                                    @NonNull AppSearchBatchResult<String, Void> result) {
-                                if (!result.isSuccess()) {
-                                    final Map<String, AppSearchResult<Void>> failures =
-                                            result.getFailures();
-                                    for (String key : failures.keySet()) {
-                                        Slog.e(TAG, "Failed deleting " + key + ", error message:"
-                                                + failures.get(key).getErrorMessage());
-                                    }
-                                }
-                            }
-                            @Override
-                            public void onSystemError(@Nullable Throwable throwable) {
-                                Slog.e(TAG, "Error removing shortcuts", throwable);
-                            }
-                        })));
-    }
-
-    @GuardedBy("mPackageItemLock")
-    @Override
-    void scheduleSaveToAppSearchLocked() {
-        final Map<String, ShortcutInfo> copy = new ArrayMap<>(mShortcuts);
-        if (!mTransientShortcuts.isEmpty()) {
-            copy.putAll(mTransientShortcuts);
-            mTransientShortcuts.clear();
-        }
-        saveShortcutsAsync(copy.values().stream().filter(ShortcutInfo::usesQuota).collect(
-                Collectors.toList()));
-    }
-
-    private void saveShortcutsAsync(
-            @NonNull final Collection<ShortcutInfo> shortcuts) {
-        Objects.requireNonNull(shortcuts);
-        if (!isAppSearchEnabled() || shortcuts.isEmpty()) {
-            // No need to invoke AppSearch when there's nothing to save.
-            return;
-        }
-        if (ShortcutService.DEBUG_REBOOT) {
-            Slog.d(TAG, "Saving shortcuts async for user=" + mShortcutUser.getUserId()
-                    + " pkg=" + getPackageName() + " ids=" + shortcuts.stream()
-                    .map(ShortcutInfo::getId).collect(Collectors.joining(",", "[", "]")));
-        }
-        runAsSystem(() -> fromAppSearch().thenAccept(session -> {
-            if (shortcuts.isEmpty()) {
-                return;
-            }
-            session.put(new PutDocumentsRequest.Builder()
-                            .addGenericDocuments(
-                                    AppSearchShortcutInfo.toGenericDocuments(shortcuts))
-                            .build(),
-                    mShortcutUser.mExecutor,
-                    new BatchResultCallback<String, Void>() {
-                        @Override
-                        public void onResult(
-                                @NonNull AppSearchBatchResult<String, Void> result) {
-                            if (!result.isSuccess()) {
-                                for (AppSearchResult<Void> k : result.getFailures().values()) {
-                                    Slog.e(TAG, k.getErrorMessage());
-                                }
-                            }
-                        }
-                        @Override
-                        public void onSystemError(@Nullable Throwable throwable) {
-                            Slog.d(TAG, "Error persisting shortcuts", throwable);
-                        }
-                    });
-        }));
-    }
-
-    @VisibleForTesting
-    void getTopShortcutsFromPersistence(AndroidFuture<List<ShortcutInfo>> cb) {
-        if (!isAppSearchEnabled()) {
-            cb.complete(null);
-        }
-        runAsSystem(() -> fromAppSearch().thenAccept(session -> {
-            SearchResults res = session.search("", getSearchSpec());
-            res.getNextPage(mShortcutUser.mExecutor, results -> {
-                if (!results.isSuccess()) {
-                    cb.completeExceptionally(new IllegalStateException(results.getErrorMessage()));
-                    return;
-                }
-                cb.complete(results.getResultValue().stream()
-                        .map(SearchResult::getGenericDocument)
-                        .map(doc -> ShortcutInfo.createFromGenericDocument(
-                                mShortcutUser.getUserId(), doc))
-                        .collect(Collectors.toList()));
-            });
-        }));
-    }
-
-    @NonNull
-    private AndroidFuture<AppSearchSession> fromAppSearch() {
-        final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
-        final AppSearchManager.SearchContext searchContext =
-                new AppSearchManager.SearchContext.Builder(getPackageName()).build();
-        AndroidFuture<AppSearchSession> future = null;
-        try {
-            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
-                    .detectAll()
-                    .penaltyLog() // TODO: change this to penaltyDeath to fix the call-site
-                    .build());
-            future = mShortcutUser.getAppSearch(searchContext);
-            synchronized (mPackageItemLock) {
-                if (!mIsAppSearchSchemaUpToDate) {
-                    future = future.thenCompose(this::setupSchema);
-                }
-                mIsAppSearchSchemaUpToDate = true;
-            }
-        } catch (Exception e) {
-            Slog.e(TAG, "Failed to create app search session. pkg="
-                    + getPackageName() + " user=" + mShortcutUser.getUserId(), e);
-            Objects.requireNonNull(future).completeExceptionally(e);
-        } finally {
-            StrictMode.setThreadPolicy(oldPolicy);
-        }
-        return Objects.requireNonNull(future);
-    }
-
     private void runAsSystem(@NonNull final Runnable fn) {
         final long callingIdentity = Binder.clearCallingIdentity();
         try {
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageItem.java b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
index dfd2e08..44789e4 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackageItem.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
@@ -187,11 +187,6 @@
         }
     }
 
-    @GuardedBy("mPackageItemLock")
-    void scheduleSaveToAppSearchLocked() {
-
-    }
-
     public JSONObject dumpCheckin(boolean clear) throws JSONException {
         final JSONObject result = new JSONObject();
         result.put(KEY_NAME, mPackageName);
@@ -221,10 +216,7 @@
         }
         synchronized (mPackageItemLock) {
             path.getParentFile().mkdirs();
-            // TODO: Since we are persisting shortcuts into AppSearch, we should read from/write to
-            //  AppSearch as opposed to maintaining a separate XML file.
             saveToFileLocked(path, false /*forBackup*/);
-            scheduleSaveToAppSearchLocked();
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java b/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java
index 47a140a..c5899ae 100644
--- a/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java
+++ b/services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java
@@ -521,8 +521,7 @@
                 if (DEBUG) {
                     Slog.d(TAG, "Removing " + shortcutId + " as dynamic");
                 }
-                ps.deleteDynamicWithId(shortcutId, /*ignoreInvisible=*/ false,
-                        /*wasPushedOut=*/ false);
+                ps.deleteDynamicWithId(shortcutId, /*ignoreInvisible=*/ false);
             }
 
             ps.adjustRanks(); // Shouldn't be needed, but just in case.
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 1052c94..2785da5 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -113,7 +113,6 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
-import com.android.internal.infra.AndroidFuture;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.DumpUtils;
@@ -475,8 +474,6 @@
     @GuardedBy("mServiceLock")
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
-    private final boolean mIsAppSearchEnabled;
-
     private ComponentName mChooserActivity;
 
     static class InvalidFileFormatException extends Exception {
@@ -519,9 +516,6 @@
 
         mShortcutRequestPinProcessor = new ShortcutRequestPinProcessor(this, mServiceLock);
         mShortcutDumpFiles = new ShortcutDumpFiles(this);
-        mIsAppSearchEnabled = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.SHORTCUT_APPSEARCH_INTEGRATION, false)
-                && !injectIsLowRamDevice();
 
         if (onlyForPackageManagerApis) {
             return; // Don't do anything further.  For unit tests only.
@@ -559,10 +553,6 @@
         injectRegisterRoleHoldersListener(mOnRoleHoldersChangedListener);
     }
 
-    boolean isAppSearchEnabled() {
-        return mIsAppSearchEnabled;
-    }
-
     long getStatStartTime() {
         return mStatLogger.getTime();
     }
@@ -757,8 +747,6 @@
         if (DEBUG || DEBUG_REBOOT) {
             Slog.d(TAG, "unloadUserLocked: userId=" + userId);
         }
-        // Cancel any ongoing background tasks.
-        getUserShortcutsLocked(userId).cancelAllInFlightTasks();
 
         // Save all dirty information.
         saveDirtyInfo();
@@ -2298,20 +2286,20 @@
     }
 
     @Override
-    public void requestPinShortcut(String packageName, ShortcutInfo shortcut,
-            IntentSender resultIntent, int userId, AndroidFuture<String> ret) {
+    public boolean requestPinShortcut(String packageName, ShortcutInfo shortcut,
+            IntentSender resultIntent, int userId) {
         Objects.requireNonNull(shortcut);
         Preconditions.checkArgument(shortcut.isEnabled(), "Shortcut must be enabled");
         Preconditions.checkArgument(
                 !shortcut.isExcludedFromSurfaces(ShortcutInfo.SURFACE_LAUNCHER),
                 "Shortcut excluded from launcher cannot be pinned");
-        ret.complete(String.valueOf(requestPinItem(
-                packageName, userId, shortcut, null, null, resultIntent)));
+        return requestPinItem(
+                packageName, userId, shortcut, null, null, resultIntent);
     }
 
     @Override
-    public void createShortcutResultIntent(String packageName, ShortcutInfo shortcut, int userId,
-            AndroidFuture<Intent> ret) throws RemoteException {
+    public Intent createShortcutResultIntent(String packageName,
+            ShortcutInfo shortcut, int userId) throws RemoteException {
         Objects.requireNonNull(shortcut);
         Preconditions.checkArgument(shortcut.isEnabled(), "Shortcut must be enabled");
         verifyCaller(packageName, userId);
@@ -2323,7 +2311,7 @@
             intent = mShortcutRequestPinProcessor.createShortcutResultIntent(shortcut, userId);
         }
         verifyStates();
-        ret.complete(intent);
+        return intent;
     }
 
     /**
@@ -2471,8 +2459,7 @@
                 if (!ps.isShortcutExistsAndVisibleToPublisher(id)) {
                     continue;
                 }
-                ShortcutInfo removed = ps.deleteDynamicWithId(id, /*ignoreInvisible=*/ true,
-                        /*wasPushedOut*/ false);
+                ShortcutInfo removed = ps.deleteDynamicWithId(id, /*ignoreInvisible=*/ true);
                 if (removed == null) {
                     if (changedShortcuts == null) {
                         changedShortcuts = new ArrayList<>(1);
@@ -3096,51 +3083,6 @@
         }
 
         @Override
-        public void getShortcutsAsync(int launcherUserId,
-                @NonNull String callingPackage, long changedSince,
-                @Nullable String packageName, @Nullable List<String> shortcutIds,
-                @Nullable List<LocusId> locusIds, @Nullable ComponentName componentName,
-                int queryFlags, int userId, int callingPid, int callingUid,
-                @NonNull AndroidFuture<List<ShortcutInfo>> cb) {
-            final List<ShortcutInfo> ret = getShortcuts(launcherUserId, callingPackage,
-                    changedSince, packageName, shortcutIds, locusIds, componentName, queryFlags,
-                    userId, callingPid, callingUid);
-            if (shortcutIds == null || packageName == null || ret.size() >= shortcutIds.size()) {
-                // skip persistence layer if not querying by id in a specific package or all
-                // shortcuts have already been found.
-                cb.complete(ret);
-                return;
-            }
-            final ShortcutPackage p;
-            synchronized (mServiceLock) {
-                p = getUserShortcutsLocked(userId).getPackageShortcutsIfExists(packageName);
-            }
-            if (p == null) {
-                cb.complete(ret);
-                return; // Bail-out directly if package doesn't exist.
-            }
-            // fetch remaining shortcuts from persistence layer
-            final ArraySet<String> ids = new ArraySet<>(shortcutIds);
-            // remove the ids that are already fetched
-            ret.stream().map(ShortcutInfo::getId).collect(Collectors.toList()).forEach(ids::remove);
-
-            int flags = ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER;
-            if ((queryFlags & ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY) != 0) {
-                flags = ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO;
-            } else if ((queryFlags & ShortcutQuery.FLAG_GET_PERSONS_DATA) != 0) {
-                flags &= ~ShortcutInfo.CLONE_REMOVE_PERSON;
-            }
-            final int cloneFlag = flags;
-
-            p.getShortcutByIdsAsync(ids, shortcuts -> {
-                if (shortcuts != null) {
-                    shortcuts.stream().map(si -> si.clone(cloneFlag)).forEach(ret::add);
-                }
-                cb.complete(ret);
-            });
-        }
-
-        @Override
         public boolean isPinnedByCaller(int launcherUserId, @NonNull String callingPackage,
                 @NonNull String packageName, @NonNull String shortcutId, int userId) {
             Preconditions.checkStringNotEmpty(packageName, "packageName");
@@ -3183,27 +3125,6 @@
             return list.size() == 0 ? null : list.get(0);
         }
 
-        private void getShortcutInfoAsync(
-                int launcherUserId, @NonNull String packageName, @NonNull String shortcutId,
-                int userId, @NonNull Consumer<ShortcutInfo> cb) {
-            Preconditions.checkStringNotEmpty(packageName, "packageName");
-            Preconditions.checkStringNotEmpty(shortcutId, "shortcutId");
-
-            throwIfUserLockedL(userId);
-            throwIfUserLockedL(launcherUserId);
-
-            final ShortcutPackage p;
-            synchronized (mServiceLock) {
-                p = getUserShortcutsLocked(userId).getPackageShortcutsIfExists(packageName);
-            }
-            if (p == null) {
-                cb.accept(null);
-                return;
-            }
-            p.getShortcutByIdsAsync(Collections.singleton(shortcutId), shortcuts ->
-                    cb.accept(shortcuts == null || shortcuts.isEmpty() ? null : shortcuts.get(0)));
-        }
-
         @Override
         public void pinShortcuts(int launcherUserId,
                 @NonNull String callingPackage, @NonNull String packageName,
@@ -3388,48 +3309,6 @@
         }
 
         @Override
-        public void createShortcutIntentsAsync(int launcherUserId,
-                @NonNull String callingPackage, @NonNull String packageName,
-                @NonNull String shortcutId, int userId, int callingPid,
-                int callingUid, @NonNull AndroidFuture<Intent[]> cb) {
-            // Calling permission must be checked by LauncherAppsImpl.
-            Preconditions.checkStringNotEmpty(packageName, "packageName can't be empty");
-            Preconditions.checkStringNotEmpty(shortcutId, "shortcutId can't be empty");
-
-            // Check in memory shortcut first
-            synchronized (mServiceLock) {
-                throwIfUserLockedL(userId);
-                throwIfUserLockedL(launcherUserId);
-
-                getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
-                        .attemptToRestoreIfNeededAndSave();
-
-                final boolean getPinnedByAnyLauncher =
-                        canSeeAnyPinnedShortcut(callingPackage, launcherUserId,
-                                callingPid, callingUid);
-
-                // Make sure the shortcut is actually visible to the launcher.
-                final ShortcutInfo si = getShortcutInfoLocked(
-                        launcherUserId, callingPackage, packageName, shortcutId, userId,
-                        getPinnedByAnyLauncher);
-                if (si != null) {
-                    if (!si.isEnabled() || !(si.isAlive() || getPinnedByAnyLauncher)) {
-                        Log.e(TAG, "Shortcut " + shortcutId + " does not exist or disabled");
-                        cb.complete(null);
-                        return;
-                    }
-                    cb.complete(si.getIntents());
-                    return;
-                }
-            }
-
-            // Otherwise check persisted shortcuts
-            getShortcutInfoAsync(launcherUserId, packageName, shortcutId, userId, si -> {
-                cb.complete(si == null ? null : si.getIntents());
-            });
-        }
-
-        @Override
         public void addListener(@NonNull ShortcutChangeListener listener) {
             synchronized (mServiceLock) {
                 mListeners.add(Objects.requireNonNull(listener));
@@ -3534,41 +3413,6 @@
             }
         }
 
-        @Override
-        public void getShortcutIconFdAsync(int launcherUserId, @NonNull String callingPackage,
-                @NonNull String packageName, @NonNull String shortcutId, int userId,
-                @NonNull AndroidFuture<ParcelFileDescriptor> cb) {
-            Objects.requireNonNull(callingPackage, "callingPackage");
-            Objects.requireNonNull(packageName, "packageName");
-            Objects.requireNonNull(shortcutId, "shortcutId");
-
-            // Checks shortcuts in memory first
-            final ShortcutPackage p;
-            synchronized (mServiceLock) {
-                throwIfUserLockedL(userId);
-                throwIfUserLockedL(launcherUserId);
-
-                getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
-                        .attemptToRestoreIfNeededAndSave();
-
-                p = getUserShortcutsLocked(userId).getPackageShortcutsIfExists(packageName);
-                if (p == null) {
-                    cb.complete(null);
-                    return;
-                }
-
-                final ShortcutInfo shortcutInfo = p.findShortcutById(shortcutId);
-                if (shortcutInfo != null) {
-                    cb.complete(getShortcutIconParcelFileDescriptor(p, shortcutInfo));
-                    return;
-                }
-            }
-
-            // Otherwise check persisted shortcuts
-            getShortcutInfoAsync(launcherUserId, packageName, shortcutId, userId, si ->
-                    cb.complete(getShortcutIconParcelFileDescriptor(p, si)));
-        }
-
         @Nullable
         private ParcelFileDescriptor getShortcutIconParcelFileDescriptor(
                 @Nullable final ShortcutPackage p, @Nullable final ShortcutInfo shortcutInfo) {
@@ -3619,44 +3463,6 @@
             }
         }
 
-        @Override
-        public void getShortcutIconUriAsync(int launcherUserId, @NonNull String launcherPackage,
-                @NonNull String packageName, @NonNull String shortcutId, int userId,
-                @NonNull AndroidFuture<String> cb) {
-            Objects.requireNonNull(launcherPackage, "launcherPackage");
-            Objects.requireNonNull(packageName, "packageName");
-            Objects.requireNonNull(shortcutId, "shortcutId");
-
-            // Checks shortcuts in memory first
-            synchronized (mServiceLock) {
-                throwIfUserLockedL(userId);
-                throwIfUserLockedL(launcherUserId);
-
-                getLauncherShortcutsLocked(launcherPackage, userId, launcherUserId)
-                        .attemptToRestoreIfNeededAndSave();
-
-                final ShortcutPackage p = getUserShortcutsLocked(userId)
-                        .getPackageShortcutsIfExists(packageName);
-                if (p == null) {
-                    cb.complete(null);
-                    return;
-                }
-
-                final ShortcutInfo shortcutInfo = p.findShortcutById(shortcutId);
-                if (shortcutInfo != null) {
-                    cb.complete(getShortcutIconUriInternal(launcherUserId, launcherPackage,
-                            packageName, shortcutInfo, userId));
-                    return;
-                }
-            }
-
-            // Otherwise check persisted shortcuts
-            getShortcutInfoAsync(launcherUserId, packageName, shortcutId, userId, si -> {
-                cb.complete(si == null ? null : getShortcutIconUriInternal(launcherUserId,
-                        launcherPackage, packageName, si, userId));
-            });
-        }
-
         private String getShortcutIconUriInternal(int launcherUserId,
                 @NonNull String launcherPackage, @NonNull String packageName,
                 @NonNull ShortcutInfo shortcutInfo, int userId) {
@@ -3865,7 +3671,6 @@
             synchronized (mServiceLock) {
                 if (mHandler.hasCallbacks(mSaveDirtyInfoRunner)) {
                     mHandler.removeCallbacks(mSaveDirtyInfoRunner);
-                    forEachLoadedUserLocked(ShortcutUser::cancelAllInFlightTasks);
                     saveDirtyInfo();
                 }
                 mShutdown.set(true);
diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java
index b35f9c2..bc8cc7b 100644
--- a/services/core/java/com/android/server/pm/ShortcutUser.java
+++ b/services/core/java/com/android/server/pm/ShortcutUser.java
@@ -18,8 +18,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
-import android.app.appsearch.AppSearchManager;
-import android.app.appsearch.AppSearchSession;
 import android.content.pm.ShortcutManager;
 import android.content.pm.UserPackage;
 import android.metrics.LogMaker;
@@ -34,7 +32,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.infra.AndroidFuture;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.modules.utils.TypedXmlPullParser;
@@ -83,7 +80,6 @@
     private static final String KEY_PACKAGES = "packages";
 
     final ShortcutService mService;
-    final AppSearchManager mAppSearchManager;
     final Executor mExecutor;
 
     @UserIdInt
@@ -105,14 +101,9 @@
 
     private final Object mLock = new Object();
 
-    @GuardedBy("mLock")
-    private final ArrayList<AndroidFuture<AppSearchSession>> mInFlightSessions = new ArrayList<>();
-
     public ShortcutUser(ShortcutService service, int userId) {
         mService = service;
         mUserId = userId;
-        mAppSearchManager = service.mContext.createContextAsUser(UserHandle.of(userId), 0)
-                .getSystemService(AppSearchManager.class);
         mExecutor = FgThread.getExecutor();
     }
 
@@ -154,12 +145,7 @@
 
     public ShortcutPackage removePackage(@NonNull String packageName) {
         final ShortcutPackage removed = mPackages.remove(packageName);
-
-        if (removed != null) {
-            removed.removeAllShortcutsAsync();
-        }
         mService.cleanupBitmapsForPackage(mUserId, packageName);
-
         return removed;
     }
 
@@ -524,7 +510,6 @@
                 Log.w(TAG, "Shortcuts for package " + sp.getPackageName() + " are being restored."
                         + " Existing non-manifeset shortcuts will be overwritten.");
             }
-            sp.removeAllShortcutsAsync();
             addPackage(sp);
             restoredPackages[0]++;
             restoredShortcuts[0] += sp.getShortcutCount();
@@ -660,47 +645,4 @@
         logger.write(logMaker.setType(MetricsEvent.SHORTCUTS_CHANGED_SHORTCUT_COUNT)
                 .setSubtype(totalSharingShortcutCount));
     }
-
-    @NonNull
-    AndroidFuture<AppSearchSession> getAppSearch(
-            @NonNull final AppSearchManager.SearchContext searchContext) {
-        final AndroidFuture<AppSearchSession> future = new AndroidFuture<>();
-        synchronized (mLock) {
-            mInFlightSessions.removeIf(CompletableFuture::isDone);
-            mInFlightSessions.add(future);
-        }
-        if (mAppSearchManager == null) {
-            future.completeExceptionally(new RuntimeException("app search manager is null"));
-            return future;
-        }
-        if (!mService.mUserManagerInternal.isUserUnlockingOrUnlocked(getUserId())) {
-            // In rare cases the user might be stopped immediate after it started, in these cases
-            // any on-going session will need to be abandoned.
-            future.completeExceptionally(new RuntimeException("User " + getUserId() + " is "));
-            return future;
-        }
-        final long callingIdentity = Binder.clearCallingIdentity();
-        try {
-            mAppSearchManager.createSearchSession(searchContext, mExecutor, result -> {
-                if (!result.isSuccess()) {
-                    future.completeExceptionally(
-                            new RuntimeException(result.getErrorMessage()));
-                    return;
-                }
-                future.complete(result.getResultValue());
-            });
-        } finally {
-            Binder.restoreCallingIdentity(callingIdentity);
-        }
-        return future;
-    }
-
-    void cancelAllInFlightTasks() {
-        synchronized (mLock) {
-            for (AndroidFuture<AppSearchSession> session : mInFlightSessions) {
-                session.cancel(true);
-            }
-            mInFlightSessions.clear();
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 17b712d..5ab5965 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -88,7 +88,9 @@
 import static com.android.hardware.input.Flags.inputManagerLifecycleSupport;
 import static com.android.hardware.input.Flags.keyboardA11yShortcutControl;
 import static com.android.hardware.input.Flags.modifierShortcutDump;
+import static com.android.hardware.input.Flags.overridePowerKeyBehaviorInFocusedWindow;
 import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
+import static com.android.server.GestureLauncherService.DOUBLE_POWER_TAP_COUNT_THRESHOLD;
 import static com.android.server.flags.Flags.modifierShortcutManagerMultiuser;
 import static com.android.server.flags.Flags.newBugreportKeyboardShortcut;
 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.SCREENSHOT_KEYCHORD_DELAY;
@@ -191,6 +193,7 @@
 import android.service.vr.IPersistentVrStateCallbacks;
 import android.speech.RecognizerIntent;
 import android.telecom.TelecomManager;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.MathUtils;
 import android.util.MutableBoolean;
@@ -431,6 +434,16 @@
             "android.intent.action.VOICE_ASSIST_RETAIL";
 
     /**
+     * Maximum amount of time in milliseconds between consecutive power onKeyDown events to be
+     * considered a multi-press, only used for the power button.
+     * Note: To maintain backwards compatibility for the power button, we are measuring the times
+     * between consecutive down events instead of the first tap's up event and the second tap's
+     * down event.
+     */
+    @VisibleForTesting public static final int POWER_MULTI_PRESS_TIMEOUT_MILLIS =
+            ViewConfiguration.getMultiPressTimeout();
+
+    /**
      * Lock protecting internal state.  Must not call out into window
      * manager with lock held.  (This lock will be acquired in places
      * where the window manager is calling in with its own lock held.)
@@ -491,6 +504,32 @@
 
     private WindowWakeUpPolicy mWindowWakeUpPolicy;
 
+    /**
+     * The three variables below are used for custom power key gesture detection in
+     * PhoneWindowManager. They are used to detect when the power button has been double pressed
+     * and, when it does happen, makes the behavior overrideable by the app.
+     *
+     * We cannot use the {@link PowerKeyRule} for this because multi-press power gesture detection
+     * and behaviors are handled by {@link com.android.server.GestureLauncherService}, and the
+     * {@link PowerKeyRule} only handles single and long-presses of the power button. As a result,
+     * overriding the double tap behavior requires custom gesture detection here that mimics the
+     * logic in {@link com.android.server.GestureLauncherService}.
+     *
+     * Long-term, it would be beneficial to move all power gesture detection to
+     * {@link PowerKeyRule} so that this custom logic isn't required.
+     */
+    // Time of last power down event.
+    private long mLastPowerDown;
+
+    // Number of power button events consecutively triggered (within a specific timeout threshold).
+    private int mPowerButtonConsecutiveTaps = 0;
+
+    // Whether a double tap of the power button has been detected.
+    volatile boolean mDoubleTapPowerDetected;
+
+    // Runnable that is queued on a delay when the first power keyDown event is sent to the app.
+    private Runnable mPowerKeyDelayedRunnable = null;
+
     boolean mSafeMode;
 
     // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
@@ -1079,6 +1118,11 @@
         mPowerKeyHandled = mPowerKeyHandled || hungUp
                 || handledByPowerManager || isKeyGestureTriggered
                 || mKeyCombinationManager.isPowerKeyIntercepted();
+
+        if (overridePowerKeyBehaviorInFocusedWindow()) {
+            mPowerKeyHandled |= mDoubleTapPowerDetected;
+        }
+
         if (!mPowerKeyHandled) {
             if (!interactive) {
                 wakeUpFromWakeKey(event);
@@ -2651,7 +2695,18 @@
             if (mShouldEarlyShortPressOnPower) {
                 return;
             }
-            powerPress(downTime, 1 /*count*/, displayId);
+            // TODO(b/380433365): Remove deferring single power press action when refactoring.
+            if (overridePowerKeyBehaviorInFocusedWindow()) {
+                mDeferredKeyActionExecutor.cancelQueuedAction(KEYCODE_POWER);
+                mDeferredKeyActionExecutor.queueKeyAction(
+                        KEYCODE_POWER,
+                        downTime,
+                        () -> {
+                            powerPress(downTime, 1 /*count*/, displayId);
+                        });
+            } else {
+                powerPress(downTime, 1 /*count*/, displayId);
+            }
         }
 
         @Override
@@ -2682,7 +2737,17 @@
 
         @Override
         void onMultiPress(long downTime, int count, int displayId) {
-            powerPress(downTime, count, displayId);
+            if (overridePowerKeyBehaviorInFocusedWindow()) {
+                mDeferredKeyActionExecutor.cancelQueuedAction(KEYCODE_POWER);
+                mDeferredKeyActionExecutor.queueKeyAction(
+                        KEYCODE_POWER,
+                        downTime,
+                        () -> {
+                            powerPress(downTime, count, displayId);
+                        });
+            } else {
+                powerPress(downTime, count, displayId);
+            }
         }
 
         @Override
@@ -3459,6 +3524,12 @@
             }
         }
 
+        if (overridePowerKeyBehaviorInFocusedWindow() && event.getKeyCode() == KEYCODE_POWER
+                && event.getAction() == KeyEvent.ACTION_UP
+                && mDoubleTapPowerDetected) {
+            mDoubleTapPowerDetected = false;
+        }
+
         return needToConsumeKey ? keyConsumed : keyNotConsumed;
     }
 
@@ -3974,6 +4045,8 @@
                     sendSystemKeyToStatusBarAsync(event);
                     return true;
                 }
+            case KeyEvent.KEYCODE_POWER:
+                return interceptPowerKeyBeforeDispatching(focusedToken, event);
             case KeyEvent.KEYCODE_SCREENSHOT:
                 if (firstDown) {
                     interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
@@ -4029,6 +4102,8 @@
                     sendSystemKeyToStatusBarAsync(event);
                     return true;
                 }
+            case KeyEvent.KEYCODE_POWER:
+                return interceptPowerKeyBeforeDispatching(focusedToken, event);
         }
         if (isValidGlobalKey(keyCode)
                 && mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
@@ -4039,6 +4114,90 @@
         return (metaState & KeyEvent.META_META_ON) != 0;
     }
 
+    /**
+     * Called by interceptKeyBeforeDispatching to handle interception logic for KEYCODE_POWER
+     * KeyEvents.
+     *
+     * @return true if intercepting the key, false if sending to app.
+     */
+    private boolean interceptPowerKeyBeforeDispatching(IBinder focusedToken, KeyEvent event) {
+        if (!overridePowerKeyBehaviorInFocusedWindow()) {
+            //Flag disabled: intercept the power key and do not send to app.
+            return true;
+        }
+        if (event.getKeyCode() != KEYCODE_POWER) {
+            Log.wtf(TAG, "interceptPowerKeyBeforeDispatching received a non-power KeyEvent "
+                    + "with key code: " + event.getKeyCode());
+            return false;
+        }
+
+        // Intercept keys (don't send to app) for 3x, 4x, 5x gestures)
+        if (mPowerButtonConsecutiveTaps > DOUBLE_POWER_TAP_COUNT_THRESHOLD) {
+            setDeferredKeyActionsExecutableAsync(KEYCODE_POWER, event.getDownTime());
+            return true;
+        }
+
+        // UP key; just reuse the original decision.
+        if (event.getAction() == KeyEvent.ACTION_UP) {
+            final Set<Integer> consumedKeys = mConsumedKeysForDevice.get(event.getDeviceId());
+            return consumedKeys != null
+                    && consumedKeys.contains(event.getKeyCode());
+        }
+
+        KeyInterceptionInfo info =
+                mWindowManagerInternal.getKeyInterceptionInfoFromToken(focusedToken);
+
+        if (info == null || !mButtonOverridePermissionChecker.canWindowOverridePowerKey(mContext,
+                info.windowOwnerUid, info.inputFeaturesFlags)) {
+            // The focused window does not have the permission to override power key behavior.
+            if (DEBUG_INPUT) {
+                String interceptReason = "";
+                if (info == null) {
+                    interceptReason = "Window is null";
+                } else if (!mButtonOverridePermissionChecker.canAppOverrideSystemKey(mContext,
+                        info.windowOwnerUid)) {
+                    interceptReason = "Application does not have "
+                            + "OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW permission";
+                } else {
+                    interceptReason = "Window does not have inputFeatureFlag set";
+                }
+
+                Log.d(TAG, TextUtils.formatSimple("Intercepting KEYCODE_POWER event. action=%d, "
+                                + "eventTime=%d to window=%s. interceptReason=%s. "
+                                + "mDoubleTapPowerDetected=%b",
+                        event.getAction(), event.getEventTime(), (info != null)
+                                ? info.windowTitle : "null", interceptReason,
+                        mDoubleTapPowerDetected));
+            }
+            // Intercept the key (i.e. do not send to app)
+            setDeferredKeyActionsExecutableAsync(KEYCODE_POWER, event.getDownTime());
+            return true;
+        }
+
+        if (DEBUG_INPUT) {
+            Log.d(TAG, TextUtils.formatSimple("Sending KEYCODE_POWER to app. action=%d, "
+                            + "eventTime=%d to window=%s. mDoubleTapPowerDetected=%b",
+                    event.getAction(), event.getEventTime(), info.windowTitle,
+                    mDoubleTapPowerDetected));
+        }
+
+        if (!mDoubleTapPowerDetected) {
+            //Single press: post a delayed runnable for the single press power action that will be
+            // called if it's not cancelled by a double press.
+            final var downTime = event.getDownTime();
+            mPowerKeyDelayedRunnable = () ->
+                    setDeferredKeyActionsExecutableAsync(KEYCODE_POWER, downTime);
+            mHandler.postDelayed(mPowerKeyDelayedRunnable, POWER_MULTI_PRESS_TIMEOUT_MILLIS);
+        } else if (mPowerKeyDelayedRunnable != null) {
+            //Double press detected: cancel the single press runnable.
+            mHandler.removeCallbacks(mPowerKeyDelayedRunnable);
+            mPowerKeyDelayedRunnable = null;
+        }
+
+        // Focused window has permission. Send to app.
+        return false;
+    }
+
     @SuppressLint("MissingPermission")
     private void initKeyGestures() {
         if (!useKeyGestureEventHandler()) {
@@ -4562,6 +4721,11 @@
             return true;
         }
 
+        if (overridePowerKeyBehaviorInFocusedWindow() && keyCode == KEYCODE_POWER) {
+            handleUnhandledSystemKey(event);
+            return true;
+        }
+
         if (useKeyGestureEventHandler()) {
             return false;
         }
@@ -5396,8 +5560,12 @@
                         KeyEvent.actionToString(event.getAction()),
                         mPowerKeyHandled ? 1 : 0,
                         mSingleKeyGestureDetector.getKeyPressCounter(KeyEvent.KEYCODE_POWER));
-                // Any activity on the power button stops the accessibility shortcut
-                result &= ~ACTION_PASS_TO_USER;
+                if (overridePowerKeyBehaviorInFocusedWindow()) {
+                    result |= ACTION_PASS_TO_USER;
+                } else {
+                    // Any activity on the power button stops the accessibility shortcut
+                    result &= ~ACTION_PASS_TO_USER;
+                }
                 isWakeKey = false; // wake-up will be handled separately
                 if (down) {
                     interceptPowerKeyDown(event, interactiveAndAwake, isKeyGestureTriggered);
@@ -5659,6 +5827,35 @@
         }
 
         if (event.getKeyCode() == KEYCODE_POWER && event.getAction() == KeyEvent.ACTION_DOWN) {
+            if (overridePowerKeyBehaviorInFocusedWindow()) {
+                if (event.getRepeatCount() > 0 && !mHasFeatureWatch) {
+                    return;
+                }
+                if (mGestureLauncherService != null) {
+                    mGestureLauncherService.processPowerKeyDown(event);
+                }
+
+                if (detectDoubleTapPower(event)) {
+                    mDoubleTapPowerDetected = true;
+
+                    // Copy of the event for handler in case the original event gets recycled.
+                    KeyEvent eventCopy = KeyEvent.obtain(event);
+                    mDeferredKeyActionExecutor.queueKeyAction(
+                            KeyEvent.KEYCODE_POWER,
+                            eventCopy.getEventTime(),
+                            () -> {
+                                if (!handleCameraGesture(eventCopy, interactive)) {
+                                    mSingleKeyGestureDetector.interceptKey(
+                                            eventCopy, interactive, defaultDisplayOn);
+                                } else {
+                                    mSingleKeyGestureDetector.reset();
+                                }
+                                eventCopy.recycle();
+                            });
+                    return;
+                }
+            }
+
             mPowerKeyHandled = handleCameraGesture(event, interactive);
             if (mPowerKeyHandled) {
                 // handled by camera gesture.
@@ -5670,6 +5867,26 @@
         mSingleKeyGestureDetector.interceptKey(event, interactive, defaultDisplayOn);
     }
 
+    private boolean detectDoubleTapPower(KeyEvent event) {
+        //Watches use the SingleKeyGestureDetector for detecting multi-press gestures.
+        if (mHasFeatureWatch || event.getKeyCode() != KEYCODE_POWER
+                || event.getAction() != KeyEvent.ACTION_DOWN  || event.getRepeatCount() != 0) {
+            return false;
+        }
+
+        final long powerTapInterval = event.getEventTime() - mLastPowerDown;
+        mLastPowerDown = event.getEventTime();
+        if (powerTapInterval >= POWER_MULTI_PRESS_TIMEOUT_MILLIS) {
+            // Tap too slow for double press
+            mPowerButtonConsecutiveTaps = 1;
+        } else {
+            mPowerButtonConsecutiveTaps++;
+        }
+
+        return powerTapInterval < POWER_MULTI_PRESS_TIMEOUT_MILLIS
+                && mPowerButtonConsecutiveTaps == DOUBLE_POWER_TAP_COUNT_THRESHOLD;
+    }
+
     // The camera gesture will be detected by GestureLauncherService.
     private boolean handleCameraGesture(KeyEvent event, boolean interactive) {
         // camera gesture.
@@ -7526,6 +7743,12 @@
                     null)
                     == PERMISSION_GRANTED;
         }
+
+        boolean canWindowOverridePowerKey(Context context, int uid, int inputFeaturesFlags) {
+            return canAppOverrideSystemKey(context, uid)
+                    && (inputFeaturesFlags & WindowManager.LayoutParams
+                    .INPUT_FEATURE_RECEIVE_POWER_KEY_DOUBLE_PRESS) != 0;
+        }
     }
 
     private int getTargetDisplayIdForKeyEvent(KeyEvent event) {
diff --git a/services/core/java/com/android/server/power/WakefulnessSessionObserver.java b/services/core/java/com/android/server/power/WakefulnessSessionObserver.java
index 64f0693..d377c23 100644
--- a/services/core/java/com/android/server/power/WakefulnessSessionObserver.java
+++ b/services/core/java/com/android/server/power/WakefulnessSessionObserver.java
@@ -205,6 +205,13 @@
                         UserHandle.USER_ALL);
 
         mPhysicalDisplayPortIdForDefaultDisplay = getPhysicalDisplayPortId(DEFAULT_DISPLAY);
+        registerDisplayListener();
+        mPowerGroups.append(
+                Display.DEFAULT_DISPLAY_GROUP,
+                new WakefulnessSessionPowerGroup(Display.DEFAULT_DISPLAY_GROUP));
+    }
+
+    private void registerDisplayListener() {
         DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
         if (displayManager != null) {
             displayManager.registerDisplayListener(
@@ -226,12 +233,8 @@
                         }
                     },
                     mHandler,
-                    DisplayManager.EVENT_FLAG_DISPLAY_CHANGED);
+                    DisplayManager.EVENT_TYPE_DISPLAY_CHANGED);
         }
-
-        mPowerGroups.append(
-                Display.DEFAULT_DISPLAY_GROUP,
-                new WakefulnessSessionPowerGroup(Display.DEFAULT_DISPLAY_GROUP));
     }
 
     /**
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index a0bc77e..1726f0d 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -42,6 +42,7 @@
 import android.hardware.power.GpuHeadroomResult;
 import android.hardware.power.IPower;
 import android.hardware.power.SessionConfig;
+import android.hardware.power.SessionMode;
 import android.hardware.power.SessionTag;
 import android.hardware.power.SupportInfo;
 import android.hardware.power.WorkDuration;
@@ -58,6 +59,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
 import android.os.SessionCreationConfig;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -80,7 +82,6 @@
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
-import com.android.server.power.hint.HintManagerService.AppHintSession.SessionModes;
 import com.android.server.utils.Slogf;
 
 import java.io.BufferedReader;
@@ -409,6 +410,29 @@
         mEnforceCpuHeadroomUserModeCpuTimeCheck = true;
     }
 
+    private boolean tooManyPipelineThreads(int uid) {
+        synchronized (mThreadsUsageObject) {
+            ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(uid);
+            int graphicsPipelineThreadCount = 0;
+            if (threadsSet != null) {
+                // We count the graphics pipeline threads that are
+                // *not* in this session, since those in this session
+                // will be replaced. Then if the count plus the new tids
+                // is over max available graphics pipeline threads we raise
+                // an exception.
+                for (ThreadUsageTracker t : threadsSet) {
+                    if (t.isGraphicsPipeline()) {
+                        graphicsPipelineThreadCount++;
+                    }
+                }
+                if (graphicsPipelineThreadCount > MAX_GRAPHICS_PIPELINE_THREADS_COUNT) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
     private ServiceThread createCleanUpThread() {
         final ServiceThread handlerThread = new ServiceThread(TAG,
                 Process.THREAD_PRIORITY_LOWEST, true /*allowIo*/);
@@ -1307,9 +1331,9 @@
     @VisibleForTesting
     final class BinderService extends IHintManager.Stub {
         @Override
-        public IHintSession createHintSessionWithConfig(@NonNull IBinder token,
-                    @SessionTag int tag, SessionCreationConfig creationConfig,
-                    SessionConfig config) {
+        public IHintManager.SessionCreationReturn createHintSessionWithConfig(
+                    @NonNull IBinder token, @SessionTag int tag,
+                    SessionCreationConfig creationConfig, SessionConfig config) {
             if (!isHintSessionSupported()) {
                 throw new UnsupportedOperationException("PowerHintSessions are not supported!");
             }
@@ -1327,8 +1351,24 @@
             final long identity = Binder.clearCallingIdentity();
             final long durationNanos = creationConfig.targetWorkDurationNanos;
 
-            Preconditions.checkArgument(checkGraphicsPipelineValid(creationConfig, callingUid),
-                    "not enough of available graphics pipeline thread.");
+            boolean isGraphicsPipeline = false;
+            boolean isAutoTimed = false;
+            if (creationConfig.modesToEnable != null) {
+                for (int mode : creationConfig.modesToEnable) {
+                    if (mode == SessionMode.GRAPHICS_PIPELINE) {
+                        isGraphicsPipeline = true;
+                    }
+                    if (mode == SessionMode.AUTO_CPU || mode == SessionMode.AUTO_GPU) {
+                        isAutoTimed = true;
+                    }
+                }
+            }
+
+            if (isAutoTimed) {
+                Preconditions.checkArgument(isGraphicsPipeline,
+                        "graphics pipeline mode not enabled for an automatically timed session");
+            }
+
             try {
                 final IntArray nonIsolated = powerhintThreadCleanup() ? new IntArray(tids.length)
                         : null;
@@ -1446,12 +1486,8 @@
                 }
 
                 if (hs != null) {
-                    boolean isGraphicsPipeline = false;
                     if (creationConfig.modesToEnable != null) {
                         for (int sessionMode : creationConfig.modesToEnable) {
-                            if (sessionMode == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
-                                isGraphicsPipeline = true;
-                            }
                             hs.setMode(sessionMode, true);
                         }
                     }
@@ -1470,7 +1506,10 @@
                     }
                 }
 
-                return hs;
+                IHintManager.SessionCreationReturn out = new IHintManager.SessionCreationReturn();
+                out.pipelineThreadLimitExceeded = tooManyPipelineThreads(callingUid);
+                out.session = hs;
+                return out;
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -1555,12 +1594,9 @@
                 }
                 halParams.tids = params.tids;
             }
-            if (halParams.calculationWindowMillis
-                    == mDefaultCpuHeadroomCalculationWindowMillis) {
-                synchronized (mCpuHeadroomLock) {
-                    final CpuHeadroomResult res = mCpuHeadroomCache.get(halParams);
-                    if (res != null) return res;
-                }
+            synchronized (mCpuHeadroomLock) {
+                final CpuHeadroomResult res = mCpuHeadroomCache.get(halParams);
+                if (res != null) return res;
             }
             final boolean shouldCheckUserModeCpuTime =
                     mEnforceCpuHeadroomUserModeCpuTimeCheck
@@ -1583,11 +1619,8 @@
                     Slog.wtf(TAG, "CPU headroom from Power HAL is invalid");
                     return null;
                 }
-                if (halParams.calculationWindowMillis
-                        == mDefaultCpuHeadroomCalculationWindowMillis) {
-                    synchronized (mCpuHeadroomLock) {
-                        mCpuHeadroomCache.add(halParams, result);
-                    }
+                synchronized (mCpuHeadroomLock) {
+                    mCpuHeadroomCache.add(halParams, result);
                 }
                 if (shouldCheckUserModeCpuTime) {
                     synchronized (mCpuHeadroomLock) {
@@ -1698,12 +1731,9 @@
             final GpuHeadroomParams halParams = new GpuHeadroomParams();
             halParams.calculationType = params.calculationType;
             halParams.calculationWindowMillis = params.calculationWindowMillis;
-            if (halParams.calculationWindowMillis
-                    == mDefaultGpuHeadroomCalculationWindowMillis) {
-                synchronized (mGpuHeadroomLock) {
-                    final GpuHeadroomResult res = mGpuHeadroomCache.get(halParams);
-                    if (res != null) return res;
-                }
+            synchronized (mGpuHeadroomLock) {
+                final GpuHeadroomResult res = mGpuHeadroomCache.get(halParams);
+                if (res != null) return res;
             }
             // return from HAL directly
             try {
@@ -1712,11 +1742,8 @@
                     Slog.wtf(TAG, "GPU headroom from Power HAL is invalid");
                     return null;
                 }
-                if (halParams.calculationWindowMillis
-                        == mDefaultGpuHeadroomCalculationWindowMillis) {
-                    synchronized (mGpuHeadroomLock) {
-                        mGpuHeadroomCache.add(halParams, headroom);
-                    }
+                synchronized (mGpuHeadroomLock) {
+                    mGpuHeadroomCache.add(halParams, headroom);
                 }
                 return headroom;
             } catch (RemoteException e) {
@@ -1852,45 +1879,6 @@
             throw new IllegalStateException("Can't find cpu line in " + filePath);
         }
 
-        private boolean checkGraphicsPipelineValid(SessionCreationConfig creationConfig, int uid) {
-            if (creationConfig.modesToEnable == null) {
-                return true;
-            }
-            boolean setGraphicsPipeline = false;
-            for (int modeToEnable : creationConfig.modesToEnable) {
-                if (modeToEnable == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
-                    setGraphicsPipeline = true;
-                }
-            }
-            if (!setGraphicsPipeline) {
-                return true;
-            }
-
-            synchronized (mThreadsUsageObject) {
-                // count used graphics pipeline threads for the calling UID
-                // consider the case that new tids are overlapping with in session tids
-                ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(uid);
-                if (threadsSet == null) {
-                    return true;
-                }
-
-                final int newThreadCount = creationConfig.tids.length;
-                int graphicsPipelineThreadCount = 0;
-                for (ThreadUsageTracker t : threadsSet) {
-                    // count graphics pipeline threads in use
-                    // and exclude overlapping ones
-                    if (t.isGraphicsPipeline()) {
-                        graphicsPipelineThreadCount++;
-                        if (contains(creationConfig.tids, t.getTid())) {
-                            graphicsPipelineThreadCount--;
-                        }
-                    }
-                }
-                return graphicsPipelineThreadCount + newThreadCount
-                        <= MAX_GRAPHICS_PIPELINE_THREADS_COUNT;
-            }
-        }
-
         private void logPerformanceHintSessionAtom(int uid, long sessionId,
                 long targetDuration, int[] tids, @SessionTag int sessionTag) {
             FrameworkStatsLog.write(FrameworkStatsLog.PERFORMANCE_HINT_SESSION_REPORTED, uid,
@@ -1928,11 +1916,6 @@
         protected Integer mSessionId;
         protected boolean mTrackedBySF;
 
-        enum SessionModes {
-            POWER_EFFICIENCY,
-            GRAPHICS_PIPELINE,
-        };
-
         protected AppHintSession(
                 int uid, int pid, int sessionTag, int[] threadIds, IBinder token,
                 long halSessionPtr, long durationNanos, Integer sessionId) {
@@ -1985,8 +1968,8 @@
                 if (!isHintAllowed()) {
                     return;
                 }
-                Preconditions.checkArgument(targetDurationNanos > 0, "Expected"
-                        + " the target duration to be greater than 0.");
+                Preconditions.checkArgument(targetDurationNanos >= 0, "Expected"
+                        + " the target duration to be greater than or equal to 0.");
                 mNativeWrapper.halUpdateTargetWorkDuration(mHalSessionPtr, targetDurationNanos);
                 mTargetDurationNanos = targetDurationNanos;
             }
@@ -2149,6 +2132,11 @@
 
         public void setThreads(@NonNull int[] tids) {
             setThreadsInternal(tids, true);
+            if (tooManyPipelineThreads(Binder.getCallingUid())) {
+                // This is technically a success but we are going to throw a fit anyway
+                throw new ServiceSpecificException(5,
+                                    "Not enough available graphics pipeline threads.");
+            }
         }
 
         private void setThreadsInternal(int[] tids, boolean checkTid) {
@@ -2156,32 +2144,7 @@
                 throw new IllegalArgumentException("Thread id list can't be empty.");
             }
 
-
             final int callingUid = Binder.getCallingUid();
-            if (mGraphicsPipeline) {
-                synchronized (mThreadsUsageObject) {
-                    // replace original tids with new tids
-                    ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(callingUid);
-                    int graphicsPipelineThreadCount = 0;
-                    if (threadsSet != null) {
-                        // We count the graphics pipeline threads that are
-                        // *not* in this session, since those in this session
-                        // will be replaced. Then if the count plus the new tids
-                        // is over max available graphics pipeline threads we raise
-                        // an exception.
-                        for (ThreadUsageTracker t : threadsSet) {
-                            if (t.isGraphicsPipeline() && !contains(mThreadIds, t.getTid())) {
-                                graphicsPipelineThreadCount++;
-                            }
-                        }
-                        if (graphicsPipelineThreadCount + tids.length
-                                > MAX_GRAPHICS_PIPELINE_THREADS_COUNT) {
-                            throw new IllegalArgumentException(
-                                    "Not enough available graphics pipeline threads.");
-                        }
-                    }
-                }
-            }
 
             synchronized (this) {
                 if (mHalSessionPtr == 0) {
@@ -2315,15 +2278,15 @@
                 }
                 Preconditions.checkArgument(mode >= 0, "the mode Id value should be"
                         + " greater than zero.");
-                if (mode == SessionModes.POWER_EFFICIENCY.ordinal()) {
+                if (mode == SessionMode.POWER_EFFICIENCY) {
                     mPowerEfficient = enabled;
-                } else if (mode == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
+                } else if (mode == SessionMode.GRAPHICS_PIPELINE) {
                     mGraphicsPipeline = enabled;
                 }
                 mNativeWrapper.halSetMode(mHalSessionPtr, mode, enabled);
             }
             if (enabled) {
-                if (mode == SessionModes.POWER_EFFICIENCY.ordinal()) {
+                if (mode == SessionMode.POWER_EFFICIENCY) {
                     if (!mHasBeenPowerEfficient) {
                         mHasBeenPowerEfficient = true;
                         synchronized (mSessionSnapshotMapLock) {
@@ -2342,7 +2305,7 @@
                             sessionSnapshot.logPowerEfficientSession();
                         }
                     }
-                } else if (mode == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
+                } else if (mode == SessionMode.GRAPHICS_PIPELINE) {
                     if (!mHasBeenGraphicsPipeline) {
                         mHasBeenGraphicsPipeline = true;
                         synchronized (mSessionSnapshotMapLock) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index b71256d..e4ad56f 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -225,6 +225,7 @@
 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
 import static com.android.server.wm.ActivityTaskManagerService.getInputDispatchingTimeoutMillisLocked;
+import static com.android.server.wm.ActivityTaskManagerService.isPip2ExperimentEnabled;
 import static com.android.server.wm.IdentifierProto.HASH_CODE;
 import static com.android.server.wm.IdentifierProto.TITLE;
 import static com.android.server.wm.IdentifierProto.USER_ID;
@@ -1495,7 +1496,10 @@
             // precede the configuration change from the resize.)
             mLastReportedPictureInPictureMode = inPictureInPictureMode;
             mLastReportedMultiWindowMode = inPictureInPictureMode;
-            ensureActivityConfiguration(true /* ignoreVisibility */);
+            if (!isPip2ExperimentEnabled()) {
+                // PiP2 should handle sending out the configuration as a part of Shell Transitions.
+                ensureActivityConfiguration(true /* ignoreVisibility */);
+            }
             if (inPictureInPictureMode && findMainWindow() == null
                     && task.topRunningActivity() == this) {
                 // Prevent malicious app entering PiP without valid WindowState, which can in turn
diff --git a/services/core/java/com/android/server/wm/ActivitySnapshotController.java b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
index cfd3248..26b7cc6 100644
--- a/services/core/java/com/android/server/wm/ActivitySnapshotController.java
+++ b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
@@ -34,6 +34,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.wm.BaseAppSnapshotPersister.PersistInfoProvider;
+import com.android.window.flags.Flags;
 
 import java.io.File;
 import java.io.PrintWriter;
@@ -498,50 +499,73 @@
         }
         final TaskFragment currTF = currentActivity.getTaskFragment();
         final TaskFragment prevTF = initPrev.getTaskFragment();
-        final TaskFragment prevAdjacentTF = prevTF != null
-                ? prevTF.getAdjacentTaskFragment() : null;
-        if (currTF == prevTF && currTF != null || prevAdjacentTF == null) {
-            // Current activity and previous one is in the same task fragment, or
-            // previous activity is not in a task fragment, or
-            // previous activity's task fragment doesn't adjacent to any others.
+        if (currTF == prevTF || prevTF.asTask() != null || !prevTF.hasAdjacentTaskFragment()) {
+            // Current activity and the initPrev is in the same TaskFragment,
+            // or initPrev activity is a direct child of Task,
+            // or initPrev activity doesn't have an adjacent.
+            // A
+            // B
             if (!inTransition || isInParticipant(initPrev, mTmpTransitionParticipants)) {
                 result.add(initPrev);
             }
             return;
         }
 
-        if (prevAdjacentTF == currTF) {
+        if (currTF.isAdjacentTo(prevTF)) {
             // previous activity A is adjacent to current activity B.
             // Try to find anyone below previous activityA, which are C and D if exists.
             // A | B
             // C (| D)
             getActivityBelow(initPrev, inTransition, result);
-        } else {
-            // previous activity C isn't adjacent to current activity A.
-            // A
-            // B | C
-            final Task prevAdjacentTask = prevAdjacentTF.getTask();
-            if (prevAdjacentTask == currentTask) {
-                final int currentIndex = currTF != null
-                        ? currentTask.mChildren.indexOf(currTF)
-                        : currentTask.mChildren.indexOf(currentActivity);
-                final int prevAdjacentIndex =
-                        prevAdjacentTask.mChildren.indexOf(prevAdjacentTF);
-                // prevAdjacentTF already above currentActivity
-                if (prevAdjacentIndex > currentIndex) {
-                    return;
-                }
+            return;
+        }
+
+        // The initPrev activity has an adjacent that is different from current activity.
+        // A
+        // B | C
+        final int currentIndex = currTF.asTask() != null
+                ? currentTask.mChildren.indexOf(currentActivity)
+                : currentTask.mChildren.indexOf(currTF);
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            final int prevAdjacentIndex = currentTask.mChildren.indexOf(
+                    prevTF.getAdjacentTaskFragment());
+            if (prevAdjacentIndex > currentIndex) {
+                // PrevAdjacentTF already above currentActivity
+                return;
             }
+            // Add both the one below, and its adjacent.
             if (!inTransition || isInParticipant(initPrev, mTmpTransitionParticipants)) {
                 result.add(initPrev);
             }
-            // prevAdjacentTF is adjacent to another one
+            final ActivityRecord prevAdjacentActivity = prevTF.getAdjacentTaskFragment()
+                    .getTopMostActivity();
+            if (prevAdjacentActivity != null && (!inTransition
+                    || isInParticipant(prevAdjacentActivity, mTmpTransitionParticipants))) {
+                result.add(prevAdjacentActivity);
+            }
+            return;
+        }
+
+        final boolean hasAdjacentAboveCurrent = prevTF.forOtherAdjacentTaskFragments(
+                prevAdjacentTF -> {
+                    final int prevAdjacentIndex = currentTask.mChildren.indexOf(prevAdjacentTF);
+                    return prevAdjacentIndex > currentIndex;
+                });
+        if (hasAdjacentAboveCurrent) {
+            // PrevAdjacentTF already above currentActivity
+            return;
+        }
+        // Add all adjacent top.
+        if (!inTransition || isInParticipant(initPrev, mTmpTransitionParticipants)) {
+            result.add(initPrev);
+        }
+        prevTF.forOtherAdjacentTaskFragments(prevAdjacentTF -> {
             final ActivityRecord prevAdjacentActivity = prevAdjacentTF.getTopMostActivity();
             if (prevAdjacentActivity != null && (!inTransition
                     || isInParticipant(prevAdjacentActivity, mTmpTransitionParticipants))) {
                 result.add(prevAdjacentActivity);
             }
-        }
+        });
     }
 
     static boolean isInParticipant(ActivityRecord ar,
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index 6709e3a..a318c4b 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS;
 import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY;
 import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
@@ -35,6 +36,7 @@
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
 import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 
@@ -510,6 +512,14 @@
             }
 
             if (mComponentSpecified) {
+                Slog.w(TAG, "Starting home with component specified, uid=" + mCallingUid);
+                if (mService.isCallerRecents(mCallingUid)
+                        || ActivityTaskManagerService.checkPermission(MANAGE_ACTIVITY_TASKS,
+                                mCallingPid, mCallingUid) == PERMISSION_GRANTED) {
+                    // Allow home component specified from trusted callers.
+                    return false;
+                }
+
                 final ComponentName homeComponent = mIntent.getComponent();
                 final Intent homeIntent = mService.getHomeIntent();
                 final ActivityInfo aInfo = mService.mRootWindowContainer.resolveHomeActivity(
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 0aff1de..ef6f923 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -2526,9 +2526,6 @@
         task.forAllActivities(r -> {
             if (!r.attachedToProcess()) return;
             mPipModeChangedActivities.add(r);
-            // If we are scheduling pip change, then remove this activity from multi-window
-            // change list as the processing of pip change will make sure multi-window changed
-            // message is processed in the right order relative to pip changed.
             mMultiWindowModeChangedActivities.remove(r);
         });
 
diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
index 7deb6a8..dbe0faf 100644
--- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java
+++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
@@ -270,6 +270,11 @@
                     () -> callback.onCommitted(new SurfaceControl.Transaction()));
             mHandler.postDelayed(callback, BLAST_TIMEOUT_DURATION);
 
+            if (mWm.mAnimator.mPendingState == WindowAnimator.PENDING_STATE_NEED_APPLY) {
+                // Applies pending transaction before onTransactionReady to ensure the order with
+                // sync transaction. This is unlikely to happen unless animator thread is slow.
+                mWm.mAnimator.applyPendingTransaction();
+            }
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "onTransactionReady");
             mListener.onTransactionReady(mSyncId, merged);
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -353,6 +358,10 @@
                         + " for non-sync " + wc);
                 wc.mSyncGroup = null;
             }
+            if (mWm.mAnimator.mPendingState == WindowAnimator.PENDING_STATE_HAS_CHANGES
+                    && wc.mSyncState != WindowContainer.SYNC_STATE_NONE) {
+                mWm.mAnimator.mPendingState = WindowAnimator.PENDING_STATE_NEED_APPLY;
+            }
             if (mReady) {
                 mWm.mWindowPlacerLocked.requestTraversal();
             }
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index fc0df64..819395a 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -453,7 +453,7 @@
                 outPrevActivities.add(prevActivity);
                 return true;
             }
-            if (currTF.getAdjacentTaskFragment() == null) {
+            if (!currTF.hasAdjacentTaskFragment()) {
                 final TaskFragment nextTF = findNextTaskFragment(currentTask, currTF);
                 if (isSecondCompanionToFirst(currTF, nextTF)) {
                     // TF is isStacked, search bottom activity from companion TF.
@@ -476,7 +476,21 @@
                 }
             } else {
                 // If adjacent TF has companion to current TF, those two TF will be closed together.
-                final TaskFragment adjacentTF = currTF.getAdjacentTaskFragment();
+                final TaskFragment adjacentTF;
+                if (Flags.allowMultipleAdjacentTaskFragments()) {
+                    if (currTF.getAdjacentTaskFragments().size() > 2) {
+                        throw new IllegalStateException(
+                                "Not yet support 3+ adjacent for non-Task TFs");
+                    }
+                    final TaskFragment[] tmpAdjacent = new TaskFragment[1];
+                    currTF.forOtherAdjacentTaskFragments(tf -> {
+                        tmpAdjacent[0] = tf;
+                        return true;
+                    });
+                    adjacentTF = tmpAdjacent[0];
+                } else {
+                    adjacentTF = currTF.getAdjacentTaskFragment();
+                }
                 if (isSecondCompanionToFirst(currTF, adjacentTF)) {
                     // The two TFs are adjacent (visually displayed side-by-side), search if any
                     // activity below the lowest one.
@@ -533,29 +547,47 @@
             return;
         }
 
-        final TaskFragment prevTFAdjacent = prevTF.getAdjacentTaskFragment();
-        if (prevTFAdjacent == null || prevTFAdjacent.asTask() != null) {
+        if (!prevTF.hasAdjacentTaskFragment()) {
             return;
         }
-        final ActivityRecord prevActivityAdjacent =
-                prevTFAdjacent.getTopNonFinishingActivity();
-        if (prevActivityAdjacent != null) {
-            outPrevActivities.add(prevActivityAdjacent);
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            final TaskFragment prevTFAdjacent = prevTF.getAdjacentTaskFragment();
+            final ActivityRecord prevActivityAdjacent =
+                    prevTFAdjacent.getTopNonFinishingActivity();
+            if (prevActivityAdjacent != null) {
+                outPrevActivities.add(prevActivityAdjacent);
+            }
+            return;
         }
+        prevTF.forOtherAdjacentTaskFragments(prevTFAdjacent -> {
+            final ActivityRecord prevActivityAdjacent =
+                    prevTFAdjacent.getTopNonFinishingActivity();
+            if (prevActivityAdjacent != null) {
+                outPrevActivities.add(prevActivityAdjacent);
+            }
+        });
     }
 
     private static void findAdjacentActivityIfExist(@NonNull ActivityRecord mainActivity,
             @NonNull ArrayList<ActivityRecord> outList) {
         final TaskFragment mainTF = mainActivity.getTaskFragment();
-        if (mainTF == null || mainTF.getAdjacentTaskFragment() == null) {
+        if (mainTF == null || !mainTF.hasAdjacentTaskFragment()) {
             return;
         }
-        final TaskFragment adjacentTF = mainTF.getAdjacentTaskFragment();
-        final ActivityRecord topActivity = adjacentTF.getTopNonFinishingActivity();
-        if (topActivity == null) {
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            final TaskFragment adjacentTF = mainTF.getAdjacentTaskFragment();
+            final ActivityRecord topActivity = adjacentTF.getTopNonFinishingActivity();
+            if (topActivity != null) {
+                outList.add(topActivity);
+            }
             return;
         }
-        outList.add(topActivity);
+        mainTF.forOtherAdjacentTaskFragments(adjacentTF -> {
+            final ActivityRecord topActivity = adjacentTF.getTopNonFinishingActivity();
+            if (topActivity != null) {
+                outList.add(topActivity);
+            }
+        });
     }
 
     private static boolean hasTranslucentActivity(@NonNull ActivityRecord currentActivity,
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index 89d756c..4c2d849 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -50,6 +50,7 @@
 import static com.android.window.flags.Flags.balRequireOptInByPendingIntentCreator;
 import static com.android.window.flags.Flags.balShowToastsBlocked;
 import static com.android.window.flags.Flags.balStrictModeRo;
+import static com.android.window.flags.Flags.balStrictModeGracePeriod;
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 import static java.util.Objects.requireNonNull;
@@ -90,6 +91,7 @@
 import com.android.server.UiThread;
 import com.android.server.am.PendingIntentRecord;
 import com.android.server.wm.BackgroundLaunchProcessController.BalCheckConfiguration;
+import com.android.window.flags.Flags;
 
 import java.lang.annotation.Retention;
 import java.util.ArrayList;
@@ -515,7 +517,9 @@
                 return !callerExplicitOptOut();
             }
             return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
-                    == MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
+                    != MODE_BACKGROUND_ACTIVITY_START_DENIED
+                    && mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
+                    != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
         }
 
         public boolean realCallerExplicitOptInOrAutoOptIn() {
@@ -523,7 +527,9 @@
                 return !realCallerExplicitOptOut();
             }
             return mCheckedOptions.getPendingIntentBackgroundActivityStartMode()
-                    == MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
+                    != MODE_BACKGROUND_ACTIVITY_START_DENIED
+                    && mCheckedOptions.getPendingIntentBackgroundActivityStartMode()
+                    != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
         }
 
         public boolean callerExplicitOptOut() {
@@ -616,7 +622,6 @@
     }
 
     static class BalVerdict {
-
         static final BalVerdict BLOCK = new BalVerdict(BAL_BLOCK, false, "Blocked");
         static final BalVerdict ALLOW_BY_DEFAULT =
                 new BalVerdict(BAL_ALLOW_DEFAULT, false, "Default");
@@ -640,6 +645,9 @@
         }
 
         public BalVerdict withProcessInfo(String msg, WindowProcessController process) {
+            if (this == BLOCK || this == ALLOW_BY_DEFAULT || this == ALLOW_PRIVILEGED) {
+                return this;
+            }
             mProcessInfo = msg + " (uid=" + process.mUid + ",pid=" + process.getPid() + ")";
             return this;
         }
@@ -653,6 +661,10 @@
         }
 
         void setOnlyCreatorAllows(boolean onlyCreatorAllows) {
+            if (this == BLOCK) {
+                // do not modify BLOCK constant
+                return;
+            }
             mOnlyCreatorAllows = onlyCreatorAllows;
         }
 
@@ -662,6 +674,10 @@
 
         @VisibleForTesting
         BalVerdict setBasedOnRealCaller() {
+            if (this == BLOCK) {
+                // do not modify BLOCK constant
+                return this;
+            }
             mBasedOnRealCaller = true;
             return this;
         }
@@ -669,22 +685,29 @@
         public String toString() {
             StringBuilder builder = new StringBuilder();
             builder.append(balCodeToString(mCode));
-            if (DEBUG_ACTIVITY_STARTS) {
-                builder.append(" (");
-                if (mBackground) {
-                    builder.append("Background ");
+            if (this != BLOCK) {
+                if (mOnlyCreatorAllows) {
+                    builder.append(" [onlyCaller]");
+                } else if (mBasedOnRealCaller) {
+                    builder.append(" [realCaller]");
                 }
-                builder.append("Activity start ");
-                if (mCode == BAL_BLOCK) {
-                    builder.append("denied");
-                } else {
-                    builder.append("allowed: ").append(mMessage);
+                if (DEBUG_ACTIVITY_STARTS) {
+                    builder.append(" (");
+                    if (mBackground) {
+                        builder.append("Background ");
+                    }
+                    builder.append("Activity start ");
+                    if (mCode == BAL_BLOCK) {
+                        builder.append("denied");
+                    } else {
+                        builder.append("allowed: ").append(mMessage);
+                    }
+                    if (mProcessInfo != null) {
+                        builder.append(" ");
+                        builder.append(mProcessInfo);
+                    }
+                    builder.append(")");
                 }
-                if (mProcessInfo != null) {
-                    builder.append(" ");
-                    builder.append(mProcessInfo);
-                }
-                builder.append(")");
             }
             return builder.toString();
         }
@@ -785,9 +808,8 @@
                         .setBasedOnRealCaller();
         state.setResultForRealCaller(resultForRealCaller);
 
-        if (state.isPendingIntent()) {
-            resultForCaller.setOnlyCreatorAllows(
-                    resultForCaller.allows() && resultForRealCaller.blocks());
+        if (state.isPendingIntent() && resultForCaller.allows() && resultForRealCaller.blocks()) {
+            resultForCaller.setOnlyCreatorAllows(true);
         }
 
         // Handle cases with explicit opt-in
@@ -1634,18 +1656,27 @@
             return bas;
         }
 
-        TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment();
-        if (adjacentTaskFragment == null) {
+        if (!taskFragment.hasAdjacentTaskFragment()) {
             return bas;
         }
 
-        // Check the second fragment.
-        topActivity = adjacentTaskFragment.getActivity(topOfStackPredicate);
-        if (topActivity == null) {
-            return bas;
+        // Check the adjacent fragment.
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment();
+            topActivity = adjacentTaskFragment.getActivity(topOfStackPredicate);
+            if (topActivity == null) {
+                return bas;
+            }
+            return checkCrossUidActivitySwitchFromBelow(topActivity, uid, bas);
         }
-
-        return checkCrossUidActivitySwitchFromBelow(topActivity, uid, bas);
+        final BlockActivityStart[] out = { bas };
+        taskFragment.forOtherAdjacentTaskFragments(adjacentTaskFragment -> {
+            final ActivityRecord top = adjacentTaskFragment.getActivity(topOfStackPredicate);
+            if (top != null) {
+                out[0] = checkCrossUidActivitySwitchFromBelow(top, uid, out[0]);
+            }
+        });
+        return out[0];
     }
 
     /**
@@ -1882,7 +1913,14 @@
                             (state.mOriginatingPendingIntent != null));
         }
 
-        logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_GRACE_PERIOD);
+        if (logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_GRACE_PERIOD)) {
+            if (balStrictModeRo() && balStrictModeGracePeriod()) {
+                String abortDebugMessage = "Activity start is only allowed by grace period. "
+                        + "This may stop working in the future. "
+                        + "intent: " + state.mIntent;
+                strictModeLaunchAborted(state.mRealCallingUid, abortDebugMessage);
+            }
+        }
         logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_NON_APP_VISIBLE_WINDOW);
 
         if (balImprovedMetrics()) {
@@ -1926,24 +1964,29 @@
      * Logs details about the activity starts if the only reason it is allowed is the provided
      * {@code balCode}.
      */
-    private static void logIfOnlyAllowedBy(BalVerdict finalVerdict, BalState state, int balCode) {
+    private static boolean logIfOnlyAllowedBy(BalVerdict finalVerdict, BalState state,
+            int balCode) {
         if (finalVerdict.getRawCode() == balCode) {
             if (state.realCallerExplicitOptInOrAutoOptIn()
                     && state.mResultForRealCaller != null
                     && state.mResultForRealCaller.allows()
                     && state.mResultForRealCaller.getRawCode() != balCode) {
                 // real caller could allow with a different exemption
+                return false;
             } else if (state.callerExplicitOptInOrAutoOptIn()
                     && state.mResultForCaller != null
                     && state.mResultForCaller.allows()
                     && state.mResultForCaller.getRawCode() != balCode) {
                 // caller could allow with a different exemption
+                return false;
             } else {
                 // log to determine grace period length distribution
                 Slog.wtf(TAG, "Activity start ONLY allowed by " + balCodeToString(balCode) + " "
                         + finalVerdict.mMessage + ": " + state);
+                return true;
             }
         }
+        return false;
     }
 
     @VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 5c3fbdf..5fe1ceb 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -100,6 +100,7 @@
 import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_WALLPAPER;
 import static com.android.internal.protolog.WmProtoLogGroups.WM_SHOW_TRANSACTIONS;
 import static com.android.internal.util.LatencyTracker.ACTION_ROTATE_SCREEN;
+import static com.android.server.display.feature.flags.Flags.enableDisplayContentModeManagement;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
@@ -2912,6 +2913,7 @@
         // contains another opaque activity.
         if (mFixedRotationLaunchingApp != null && mFixedRotationLaunchingApp.isVisible()
                 && !mTransitionController.isCollecting()
+                && !mTransitionController.isPlayingTarget(mFixedRotationLaunchingApp)
                 && !mAtmService.mBackNavigationController.isMonitoringFinishTransition()) {
             final Transition finishTransition = mTransitionController.mFinishingTransition;
             if (finishTransition == null || !finishTransition.mParticipants.contains(
@@ -3288,6 +3290,32 @@
         return new Point(w, h);
     }
 
+    void onDisplayInfoChangeApplied() {
+        if (!enableDisplayContentModeManagement()) {
+            Slog.e(TAG, "ShouldShowSystemDecors shouldn't be updated when the flag is off.");
+        }
+
+        final boolean shouldShow;
+        if (isDefaultDisplay) {
+            shouldShow = true;
+        } else if (isPrivate()) {
+            shouldShow = false;
+        } else {
+            shouldShow = mDisplay.canHostTasks();
+        }
+
+        if (shouldShow == mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(this)) {
+            return;
+        }
+        mWmService.mDisplayWindowSettings.setShouldShowSystemDecorsLocked(this, shouldShow);
+
+        if (shouldShow) {
+            mRootWindowContainer.startSystemDecorations(this, "onDisplayInfoChangeApplied");
+        } else {
+            clearAllTasksOnDisplay(null);
+        }
+    }
+
     DisplayCutout loadDisplayCutout(int displayWidth, int displayHeight) {
         if (mDisplayPolicy == null || mInitialDisplayCutout == null) {
             return null;
@@ -6522,10 +6550,8 @@
         return mRemoving;
     }
 
-    void remove() {
-        mRemoving = true;
+    private void clearAllTasksOnDisplay(@Nullable Runnable clearTasksCallback) {
         Task lastReparentedRootTask;
-
         mRootWindowContainer.mTaskSupervisor.beginDeferResume();
         try {
             lastReparentedRootTask = reduceOnAllTaskDisplayAreas((taskDisplayArea, rootTask) -> {
@@ -6538,10 +6564,9 @@
         } finally {
             mRootWindowContainer.mTaskSupervisor.endDeferResume();
         }
-        mRemoved = true;
 
-        if (mContentRecorder != null) {
-            mContentRecorder.stopRecording();
+        if (clearTasksCallback != null) {
+            clearTasksCallback.run();
         }
 
         // Only update focus/visibility for the last one because there may be many root tasks are
@@ -6549,6 +6574,19 @@
         if (lastReparentedRootTask != null) {
             lastReparentedRootTask.resumeNextFocusAfterReparent();
         }
+    }
+
+    void remove() {
+        mRemoving = true;
+
+        clearAllTasksOnDisplay(() -> {
+            mRemoved = true;
+
+            if (mContentRecorder != null) {
+                mContentRecorder.stopRecording();
+            }
+        });
+
         releaseSelfIfNeeded();
         mDisplayPolicy.release();
 
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
index 63af5c6..a017a11 100644
--- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -23,6 +23,8 @@
 import android.annotation.Nullable;
 import android.util.Slog;
 
+import com.android.window.flags.Flags;
+
 import java.util.ArrayList;
 
 /** Helper class to ensure activities are in the right visible state for a container. */
@@ -110,21 +112,37 @@
 
                 if (adjacentTaskFragments != null && adjacentTaskFragments.contains(
                         childTaskFragment)) {
-                    if (!childTaskFragment.isTranslucent(starting)
-                            && !childTaskFragment.getAdjacentTaskFragment().isTranslucent(
-                                    starting)) {
+                    final boolean isTranslucent;
+                    if (Flags.allowMultipleAdjacentTaskFragments()) {
+                        isTranslucent = childTaskFragment.isTranslucent(starting)
+                                || childTaskFragment.forOtherAdjacentTaskFragments(
+                                        adjacentTaskFragment -> {
+                                            return adjacentTaskFragment.isTranslucent(starting);
+                                        });
+                    } else {
+                        isTranslucent = childTaskFragment.isTranslucent(starting)
+                                || childTaskFragment.getAdjacentTaskFragment()
+                                .isTranslucent(starting);
+                    }
+                    if (!isTranslucent) {
                         // Everything behind two adjacent TaskFragments are occluded.
                         mBehindFullyOccludedContainer = true;
                     }
                     continue;
                 }
 
-                final TaskFragment adjacentTaskFrag = childTaskFragment.getAdjacentTaskFragment();
-                if (adjacentTaskFrag != null) {
+                if (childTaskFragment.hasAdjacentTaskFragment()) {
                     if (adjacentTaskFragments == null) {
                         adjacentTaskFragments = new ArrayList<>();
                     }
-                    adjacentTaskFragments.add(adjacentTaskFrag);
+                    if (Flags.allowMultipleAdjacentTaskFragments()) {
+                        final ArrayList<TaskFragment> adjacentTfs = adjacentTaskFragments;
+                        childTaskFragment.forOtherAdjacentTaskFragments(adjacentTf -> {
+                            adjacentTfs.add(adjacentTf);
+                        });
+                    } else {
+                        adjacentTaskFragments.add(childTaskFragment.getAdjacentTaskFragment());
+                    }
                 }
             } else if (child.asActivityRecord() != null) {
                 setActivityVisibilityState(child.asActivityRecord(), starting, resumeTopActivity);
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index cba606c..98ed6f7 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -101,7 +101,8 @@
             // isLeashReadyForDispatching (used to dispatch the leash of the control) is
             // depending on mGivenInsetsReady. Therefore, triggering notifyControlChanged here
             // again, so that the control with leash can be eventually dispatched
-            if (!mGivenInsetsReady && isServerVisible() && !givenInsetsPending) {
+            if (!mGivenInsetsReady && isServerVisible() && !givenInsetsPending
+                    && mControlTarget != null) {
                 mGivenInsetsReady = true;
                 ImeTracker.forLogging().onProgress(mStatsToken,
                         ImeTracker.PHASE_WM_POST_LAYOUT_NOTIFY_CONTROLS_CHANGED);
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 7276007..d1585d0 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -384,7 +384,7 @@
         }
         final boolean serverVisibleChanged = mServerVisible != isServerVisible;
         setServerVisible(isServerVisible);
-        if (mControl != null) {
+        if (mControl != null && mControlTarget != null) {
             final boolean positionChanged = updateInsetsControlPosition(windowState);
             if (!(positionChanged || mHasPendingPosition)
                     // The insets hint would be updated while changing the position. Here updates it
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index ce85184..9df65f6 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -371,7 +371,7 @@
         array.add(provider);
     }
 
-    void notifyControlChanged(InsetsControlTarget target, InsetsSourceProvider provider) {
+    void notifyControlChanged(@NonNull InsetsControlTarget target, InsetsSourceProvider provider) {
         addToPendingControlMaps(target, provider);
         notifyPendingInsetsControlChanged();
     }
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 0604953..790858d 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -263,10 +263,9 @@
         // should be finish together in the Task.
         if (activity != taskRoot || activity != taskTop) {
             final TaskFragment taskFragment = activity.getTaskFragment();
-            final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment();
             if (taskFragment.asTask() != null
                     || !taskFragment.isDelayLastActivityRemoval()
-                    || adjacentTaskFragment == null) {
+                    || !taskFragment.hasAdjacentTaskFragment()) {
                 // Don't block activity from finishing if the TaskFragment don't have any adjacent
                 // TaskFragment, or it won't finish together with its adjacent TaskFragment.
                 return false;
@@ -281,7 +280,7 @@
             }
 
             final boolean hasOtherActivityInTask = task.getActivity(a -> !a.finishing
-                    && a != activity && a.getTaskFragment() != adjacentTaskFragment) != null;
+                    && a != activity && !taskFragment.isAdjacentTo(a.getTaskFragment())) != null;
             if (hasOtherActivityInTask) {
                 // Do not block activity from finishing if there are another running activities
                 // after the current and adjacent TaskFragments are removed. Note that we don't
@@ -653,6 +652,10 @@
         if (!isSystemCaller) {
             task.mLockTaskUid = callingUid;
             if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
+                if (mLockTaskModeTasks.contains(task)) {
+                    ProtoLog.w(WM_DEBUG_LOCKTASK, "Already locked.");
+                    return;
+                }
                 // startLockTask() called by app, but app is not part of lock task allowlist. Show
                 // app pinning request. We will come back here with isSystemCaller true.
                 ProtoLog.w(WM_DEBUG_LOCKTASK, "Mode default, asking user");
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 4f36476..57fe0bb 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -46,6 +46,7 @@
 import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_TASKS;
 import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_WALLPAPER;
 import static com.android.internal.protolog.WmProtoLogGroups.WM_SHOW_SURFACE_ALLOC;
+import static com.android.server.display.feature.flags.Flags.enableDisplayContentModeManagement;
 import static com.android.server.policy.PhoneWindowManager.SYSTEM_DIALOG_REASON_ASSIST;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
@@ -151,6 +152,7 @@
 import com.android.server.am.ActivityManagerService;
 import com.android.server.am.AppTimeTracker;
 import com.android.server.am.UserState;
+import com.android.server.display.feature.DisplayManagerFlags;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.policy.PermissionPolicyInternal;
 import com.android.server.policy.WindowManagerPolicy;
@@ -1438,6 +1440,13 @@
                     : getDefaultTaskDisplayArea();
         }
 
+        // When display content mode management flag is enabled, the task display area is marked as
+        // removed when switching from extended display to mirroring display. We need to restart the
+        // task display area before starting the home.
+        if (enableDisplayContentModeManagement() && taskDisplayArea.isRemoved()) {
+            taskDisplayArea.restart();
+        }
+
         Intent homeIntent = null;
         ActivityInfo aInfo = null;
         if (taskDisplayArea == getDefaultTaskDisplayArea()
@@ -2856,20 +2865,24 @@
             if (display == null) {
                 return;
             }
-            // Do not start home before booting, or it may accidentally finish booting before it
-            // starts. Instead, we expect home activities to be launched when the system is ready
-            // (ActivityManagerService#systemReady).
-            if (mService.isBooted() || mService.isBooting()) {
-                startSystemDecorations(display);
-            }
+
+            startSystemDecorations(display, "displayAdded");
+
             // Drop any cached DisplayInfos associated with this display id - the values are now
             // out of date given this display added event.
             mWmService.mPossibleDisplayInfoMapper.removePossibleDisplayInfos(displayId);
         }
     }
 
-    private void startSystemDecorations(final DisplayContent displayContent) {
-        startHomeOnDisplay(mCurrentUser, "displayAdded", displayContent.getDisplayId());
+    void startSystemDecorations(final DisplayContent displayContent, String reason) {
+        // Do not start home before booting, or it may accidentally finish booting before it
+        // starts. Instead, we expect home activities to be launched when the system is ready
+        // (ActivityManagerService#systemReady).
+        if (!mService.isBooted() && !mService.isBooting()) {
+            return;
+        }
+
+        startHomeOnDisplay(mCurrentUser, reason, displayContent.getDisplayId());
         displayContent.getDisplayPolicy().notifyDisplayReady();
     }
 
@@ -2896,7 +2909,13 @@
         synchronized (mService.mGlobalLock) {
             final DisplayContent displayContent = getDisplayContent(displayId);
             if (displayContent != null) {
-                displayContent.requestDisplayUpdate(() -> clearDisplayInfoCaches(displayId));
+                displayContent.requestDisplayUpdate(
+                        () -> {
+                            clearDisplayInfoCaches(displayId);
+                            if (enableDisplayContentModeManagement()) {
+                                displayContent.onDisplayInfoChangeApplied();
+                            }
+                        });
             } else {
                 clearDisplayInfoCaches(displayId);
             }
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index 9a48d5b..d7b6d96 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -200,6 +200,7 @@
             }
             mSnapshot.startAnimation(t, snapshotAnim, type);
         }
+        setAnimatorPendingState(t);
     }
 
     void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden,
@@ -208,6 +209,14 @@
                 null /* animationCancelledCallback */, null /* snapshotAnim */, null /* freezer */);
     }
 
+    /** Indicates that there are surface operations in the pending transaction. */
+    private void setAnimatorPendingState(Transaction t) {
+        if (mService.mAnimator.mPendingState == WindowAnimator.PENDING_STATE_NONE
+                && t == mAnimatable.getPendingTransaction()) {
+            mService.mAnimator.mPendingState = WindowAnimator.PENDING_STATE_HAS_CHANGES;
+        }
+    }
+
     /** Returns whether it is currently running an animation. */
     boolean isAnimating() {
         return mAnimation != null;
@@ -357,6 +366,7 @@
         final boolean scheduleAnim = removeLeash(t, mAnimatable, leash, destroyLeash);
         mAnimationFinished = false;
         if (scheduleAnim) {
+            setAnimatorPendingState(t);
             mService.scheduleAnimationLocked();
         }
     }
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 3d0b41b..3634bc9 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -1887,6 +1887,11 @@
         return lastReparentedRootTask;
     }
 
+    // TODO(b/385263090): Remove this method
+    void restart() {
+        mRemoved = false;
+    }
+
     /**
      * Returns the {@link TaskDisplayArea} to which root tasks should be reparented.
      *
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index cb6b690..367adc3 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -518,11 +518,14 @@
         }
     }
 
-    // TODO(b/373709676): update usages.
     /** @deprecated b/373709676 replace with {@link #getAdjacentTaskFragments()}. */
     @Deprecated
     @Nullable
     TaskFragment getAdjacentTaskFragment() {
+        if (Flags.allowMultipleAdjacentTaskFragments()) {
+            throw new IllegalStateException("allowMultipleAdjacentTaskFragments is enabled. "
+                    + "Use #getAdjacentTaskFragments instead");
+        }
         return mAdjacentTaskFragment;
     }
 
@@ -3523,10 +3526,18 @@
                 throw new IllegalStateException("allowMultipleAdjacentTaskFragments must be"
                         + " enabled to set more than two TaskFragments adjacent to each other.");
             }
-            if (taskFragments.size() < 2) {
+            final int size = taskFragments.size();
+            if (size < 2) {
                 throw new IllegalArgumentException("Adjacent TaskFragments must contain at least"
-                        + " two TaskFragments, but only " + taskFragments.size()
-                        + " were provided.");
+                        + " two TaskFragments, but only " + size + " were provided.");
+            }
+            if (size > 2) {
+                for (int i = 0; i < size; i++) {
+                    if (taskFragments.valueAt(i).asTask() == null) {
+                        throw new IllegalArgumentException(
+                                "Not yet support 3+ adjacent for non-Task TFs");
+                    }
+                }
             }
             mAdjacentSet = taskFragments;
         }
@@ -3604,6 +3615,10 @@
             return false;
         }
 
+        int size() {
+            return mAdjacentSet.size();
+        }
+
         @Override
         public boolean equals(@Nullable Object o) {
             if (this == o) {
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 49c8559..790ae1e 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -26,6 +26,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.os.HandlerExecutor;
 import android.os.Trace;
@@ -38,6 +39,8 @@
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 
 /**
@@ -86,6 +89,25 @@
 
     private final SurfaceControl.Transaction mTransaction;
 
+    /** The pending transaction is applied. */
+    static final int PENDING_STATE_NONE = 0;
+    /** There are some (significant) operations set to the pending transaction. */
+    static final int PENDING_STATE_HAS_CHANGES = 1;
+    /** The pending transaction needs to be applied before sending sync transaction to shell. */
+    static final int PENDING_STATE_NEED_APPLY = 2;
+
+    @IntDef(prefix = { "PENDING_STATE_" }, value = {
+            PENDING_STATE_NONE,
+            PENDING_STATE_HAS_CHANGES,
+            PENDING_STATE_NEED_APPLY,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface PendingState {}
+
+    /** The global state of pending transaction. */
+    @PendingState
+    int mPendingState;
+
     WindowAnimator(final WindowManagerService service) {
         mService = service;
         mContext = service.mContext;
@@ -217,6 +239,7 @@
         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "applyTransaction");
         mTransaction.apply();
         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+        mPendingState = PENDING_STATE_NONE;
         mService.mWindowTracing.logState("WindowAnimator");
         ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate");
 
@@ -296,8 +319,19 @@
         return mAnimationFrameCallbackScheduled;
     }
 
-    Choreographer getChoreographer() {
-        return mChoreographer;
+    void applyPendingTransaction() {
+        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "applyPendingTransaction");
+        mPendingState = PENDING_STATE_NONE;
+        final int numDisplays = mService.mRoot.getChildCount();
+        if (numDisplays == 1) {
+            mService.mRoot.getChildAt(0).getPendingTransaction().apply();
+        } else {
+            for (int i = 0; i < numDisplays; i++) {
+                mTransaction.merge(mService.mRoot.getChildAt(i).getPendingTransaction());
+            }
+            mTransaction.apply();
+        }
+        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 793f189..965b224 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -9150,7 +9150,7 @@
         // handling the touch-outside event to prevent focus rapid changes back-n-forth.
         final boolean shouldDelayTouchForEmbeddedActivity = activity != null
                 && activity.isEmbedded()
-                && activity.getTaskFragment().getAdjacentTaskFragment() != null;
+                && activity.getTaskFragment().hasAdjacentTaskFragment();
 
         // For cases when there are multiple freeform windows where non-top windows are blocking
         // the gesture zones, delay handling the touch-outside event to prevent refocusing the
@@ -9529,21 +9529,41 @@
             return focusedActivity;
         }
 
-        final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment();
-        final ActivityRecord adjacentTopActivity =
-                adjacentTaskFragment != null ? adjacentTaskFragment.topRunningActivity() : null;
-        if (adjacentTopActivity == null) {
-            // Return if no adjacent activity.
+        if (!taskFragment.hasAdjacentTaskFragment()) {
             return focusedActivity;
         }
 
-        if (adjacentTopActivity.getLastWindowCreateTime()
-                < focusedActivity.getLastWindowCreateTime()) {
-            // Return if the current focus activity has more recently active window.
-            return focusedActivity;
+        if (!Flags.allowMultipleAdjacentTaskFragments()) {
+            final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment();
+            final ActivityRecord adjacentTopActivity = adjacentTaskFragment.topRunningActivity();
+            if (adjacentTopActivity == null) {
+                // Return if no adjacent activity.
+                return focusedActivity;
+            }
+
+            if (adjacentTopActivity.getLastWindowCreateTime()
+                    < focusedActivity.getLastWindowCreateTime()) {
+                // Return if the current focus activity has more recently active window.
+                return focusedActivity;
+            }
+
+            return adjacentTopActivity;
         }
 
-        return adjacentTopActivity;
+        // Find the adjacent activity with more recently active window.
+        final ActivityRecord[] mostRecentActiveActivity = { focusedActivity };
+        final long[] mostRecentActiveTime = { focusedActivity.getLastWindowCreateTime() };
+        taskFragment.forOtherAdjacentTaskFragments(adjacentTaskFragment -> {
+            final ActivityRecord adjacentTopActivity = adjacentTaskFragment.topRunningActivity();
+            if (adjacentTopActivity != null) {
+                final long lastWindowCreateTime = adjacentTopActivity.getLastWindowCreateTime();
+                if (lastWindowCreateTime > mostRecentActiveTime[0]) {
+                    mostRecentActiveTime[0] = lastWindowCreateTime;
+                    mostRecentActiveActivity[0] = adjacentTopActivity;
+                }
+            }
+        });
+        return mostRecentActiveActivity[0];
     }
 
     @NonNull
@@ -9592,14 +9612,28 @@
             return false;
         }
         final TaskFragment fromFragment = fromWin.getTaskFragment();
-        if (fromFragment == null) {
-            return false;
-        }
-        final TaskFragment adjacentFragment = fromFragment.getAdjacentTaskFragment();
-        if (adjacentFragment == null || adjacentFragment.asTask() != null) {
+        if (fromFragment == null || fromFragment.asTask() != null) {
             // Don't move the focus to another task.
             return false;
         }
+        if (!fromFragment.hasAdjacentTaskFragment()) {
+            // No adjacent window.
+            return false;
+        }
+        final TaskFragment adjacentFragment;
+        if (Flags.allowMultipleAdjacentTaskFragments()) {
+            if (fromFragment.getAdjacentTaskFragments().size() > 2) {
+                throw new IllegalStateException("Not yet support 3+ adjacent for non-Task TFs");
+            }
+            final TaskFragment[] tmpAdjacent = new TaskFragment[1];
+            fromFragment.forOtherAdjacentTaskFragments(adjacentTF -> {
+                tmpAdjacent[0] = adjacentTF;
+                return true;
+            });
+            adjacentFragment = tmpAdjacent[0];
+        } else {
+            adjacentFragment = fromFragment.getAdjacentTaskFragment();
+        }
         if (adjacentFragment.isIsolatedNav()) {
             // Don't move the focus if the adjacent TF is isolated navigation.
             return false;
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index fb197c5..e45ada9 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -80,6 +80,7 @@
 import static com.android.server.wm.ActivityRecord.State.PAUSING;
 import static com.android.server.wm.ActivityRecord.State.RESUMED;
 import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission;
+import static com.android.server.wm.ActivityTaskManagerService.isPip2ExperimentEnabled;
 import static com.android.server.wm.ActivityTaskSupervisor.REMOVE_FROM_RECENTS;
 import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK;
 import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
@@ -716,6 +717,8 @@
                 }
                 if (forceHiddenForPip) {
                     wc.asTask().setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, true /* set */);
+                }
+                if (forceHiddenForPip && !isPip2ExperimentEnabled()) {
                     // When removing pip, make sure that onStop is sent to the app ahead of
                     // onPictureInPictureModeChanged.
                     // See also PinnedStackTests#testStopBeforeMultiWindowCallbacksOnDismiss
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 68b4b6f..b43e334 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -5750,9 +5750,10 @@
                 || mKeyInterceptionInfo.layoutParamsPrivateFlags != getAttrs().privateFlags
                 || mKeyInterceptionInfo.layoutParamsType != getAttrs().type
                 || mKeyInterceptionInfo.windowTitle != getWindowTag()
-                || mKeyInterceptionInfo.windowOwnerUid != getOwningUid()) {
+                || mKeyInterceptionInfo.windowOwnerUid != getOwningUid()
+                || mKeyInterceptionInfo.inputFeaturesFlags != getAttrs().inputFeatures) {
             mKeyInterceptionInfo = new KeyInterceptionInfo(getAttrs().type, getAttrs().privateFlags,
-                    getWindowTag().toString(), getOwningUid());
+                    getWindowTag().toString(), getOwningUid(), getAttrs().inputFeatures);
         }
         return mKeyInterceptionInfo;
     }
diff --git a/services/core/jni/com_android_server_tv_TvKeys.h b/services/core/jni/com_android_server_tv_TvKeys.h
index b3ee263..babdb4c 100644
--- a/services/core/jni/com_android_server_tv_TvKeys.h
+++ b/services/core/jni/com_android_server_tv_TvKeys.h
@@ -91,8 +91,11 @@
         {KEY_TEXT, AKEYCODE_TV_TELETEXT},
         {KEY_SUBTITLE, AKEYCODE_CAPTIONS},
         {KEY_PVR, AKEYCODE_DVR},
+        {KEY_VIDEO, AKEYCODE_TV_INPUT},
         {KEY_AUDIO, AKEYCODE_MEDIA_AUDIO_TRACK},
+        {KEY_AUDIO_DESC, AKEYCODE_TV_AUDIO_DESCRIPTION},
         {KEY_OPTION, AKEYCODE_SETTINGS},
+        {KEY_DOT,  AKEYCODE_PERIOD},
 
         // Gamepad buttons
         {KEY_UP, AKEYCODE_DPAD_UP},
diff --git a/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java b/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
index fc3ec7b..4d04c8b 100644
--- a/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
+++ b/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
@@ -37,6 +37,7 @@
 import android.util.Log;
 
 import com.android.server.backup.BackupAgentTimeoutParameters;
+import com.android.server.backup.BackupManagerConstants;
 import com.android.server.backup.BackupManagerService;
 import com.android.server.backup.TransportManager;
 import com.android.server.backup.UserBackupManagerService;
@@ -162,10 +163,10 @@
 
     public static UserBackupManagerService.BackupWakeLock createBackupWakeLock(
             Application application) {
-        PowerManager powerManager =
-                (PowerManager) application.getSystemService(Context.POWER_SERVICE);
+        PowerManager powerManager = application.getSystemService(PowerManager.class);
         return new UserBackupManagerService.BackupWakeLock(
-                powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*"), 0);
+                powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*"), 0,
+                new BackupManagerConstants(Handler.getMain(), application.getContentResolver()));
     }
 
     /**
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/BroadcastHelperTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/BroadcastHelperTest.java
index 0ae7699..58e4b91 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/BroadcastHelperTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/BroadcastHelperTest.java
@@ -36,6 +36,7 @@
 import android.app.ActivityManagerInternal;
 import android.content.Context;
 import android.content.Intent;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.Message;
 import android.os.UserHandle;
@@ -233,6 +234,7 @@
 
         mBroadcastHelper.sendPackageChangedBroadcast(mMockSnapshot,
                 PACKAGE_CHANGED_TEST_PACKAGE_NAME, true /* dontKillApp */, componentNames,
-                UserHandle.USER_SYSTEM, "test" /* reason */, "test" /* reasonForTrace */);
+                UserHandle.USER_SYSTEM, "test" /* reason */, "test" /* reasonForTrace */,
+                Binder.getCallingUid());
     }
 }
diff --git a/services/tests/appfunctions/Android.bp b/services/tests/appfunctions/Android.bp
index 836f90b..e48abc2 100644
--- a/services/tests/appfunctions/Android.bp
+++ b/services/tests/appfunctions/Android.bp
@@ -33,18 +33,20 @@
     ],
 
     static_libs: [
-        "androidx.test.core",
-        "androidx.test.runner",
-        "androidx.test.ext.truth",
         "androidx.core_core-ktx",
+        "androidx.test.core",
+        "androidx.test.ext.truth",
+        "androidx.test.rules",
+        "androidx.test.runner",
+        "frameworks-base-testutils",
         "kotlin-test",
         "kotlinx_coroutines_test",
+        "mockito-kotlin2",
+        "mockito-target-extended-minus-junit4",
         "platform-test-annotations",
         "services.appfunctions",
         "servicestests-core-utils",
         "truth",
-        "frameworks-base-testutils",
-        "androidx.test.rules",
     ],
 
     libs: [
diff --git a/services/tests/appfunctions/src/com/android/server/appfunctions/AppFunctionsLoggingTest.kt b/services/tests/appfunctions/src/com/android/server/appfunctions/AppFunctionsLoggingTest.kt
new file mode 100644
index 0000000..896d2a21d
--- /dev/null
+++ b/services/tests/appfunctions/src/com/android/server/appfunctions/AppFunctionsLoggingTest.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2024 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.appfunctions
+
+import android.app.appfunctions.AppFunctionException
+import android.app.appfunctions.ExecuteAppFunctionAidlRequest
+import android.app.appfunctions.ExecuteAppFunctionRequest
+import android.app.appfunctions.ExecuteAppFunctionResponse
+import android.app.appfunctions.IAppFunctionService
+import android.app.appfunctions.IExecuteAppFunctionCallback
+import android.app.appfunctions.SafeOneTimeExecuteAppFunctionCallback
+import android.app.appsearch.GenericDocument
+import android.content.Context
+import android.content.pm.PackageManager
+import android.os.UserHandle
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.modules.utils.testing.ExtendedMockitoRule
+import com.google.common.util.concurrent.MoreExecutors
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+
+
+/**
+ * Tests that AppFunctionsStatsLog logs AppFunctionsRequestReported with the expected values.
+ */
+@RunWith(AndroidJUnit4::class)
+class AppFunctionsLoggingTest {
+    @get:Rule
+    val mExtendedMockitoRule: ExtendedMockitoRule =
+        ExtendedMockitoRule.Builder(this)
+            .mockStatic(AppFunctionsStatsLog::class.java)
+            .build()
+    private val mContext: Context get() = ApplicationProvider.getApplicationContext()
+    private val mMockPackageManager = mock<PackageManager>()
+    private val mAppFunctionsLoggerWrapper =
+        AppFunctionsLoggerWrapper(
+            mMockPackageManager,
+            MoreExecutors.directExecutor(),
+            { TEST_CURRENT_TIME_MILLIS })
+    private lateinit var mSafeCallback: SafeOneTimeExecuteAppFunctionCallback
+
+    private val mServiceImpl =
+        AppFunctionManagerServiceImpl(
+            mContext,
+            mock<RemoteServiceCaller<IAppFunctionService>>(),
+            mock<CallerValidator>(),
+            mock<ServiceHelper>(),
+            ServiceConfigImpl(),
+            mAppFunctionsLoggerWrapper)
+
+    private val mRequestInternal = ExecuteAppFunctionAidlRequest(
+        ExecuteAppFunctionRequest.Builder(TEST_TARGET_PACKAGE, TEST_FUNCTION_ID).build(),
+        UserHandle.CURRENT, TEST_CALLING_PKG, TEST_INITIAL_REQUEST_TIME_MILLIS
+    )
+
+    @Before
+    fun setup() {
+        whenever(mMockPackageManager.getPackageUid(eq(TEST_TARGET_PACKAGE), any<Int>())).thenReturn(TEST_TARGET_UID)
+        mSafeCallback = mServiceImpl.initializeSafeExecuteAppFunctionCallback(mRequestInternal, mock<IExecuteAppFunctionCallback>(), TEST_CALLING_UID)
+        mSafeCallback.setExecutionStartTimeAfterBindMillis(TEST_EXECUTION_TIME_AFTER_BIND_MILLIS)
+    }
+
+    @Test
+    fun testOnSuccess_logsSuccessResponse() {
+        val response =
+            ExecuteAppFunctionResponse(GenericDocument.Builder<GenericDocument.Builder<*>>("", "", "")
+                .setPropertyLong("longProperty", 42L).setPropertyString("stringProperty", "text").build())
+
+        mSafeCallback.onResult(response)
+
+        ExtendedMockito.verify {
+            AppFunctionsStatsLog.write(
+                /* atomId= */ eq<Int>(AppFunctionsStatsLog.APP_FUNCTIONS_REQUEST_REPORTED),
+                /* callerPackageUid= */ eq<Int>(TEST_CALLING_UID),
+                /* targetPackageUid= */ eq<Int>(TEST_TARGET_UID),
+                /* errorCode= */ eq<Int>(AppFunctionsLoggerWrapper.SUCCESS_RESPONSE_CODE),
+                /* requestSizeBytes= */ eq<Int>(mRequestInternal.clientRequest.requestDataSize),
+                /* responseSizeBytes= */ eq<Int>(response.responseDataSize),
+                /* requestDurationMs= */ eq<Long>(TEST_EXPECTED_E2E_DURATION_MILLIS),
+                /* requestOverheadMs= */ eq<Long>(TEST_EXPECTED_OVERHEAD_DURATION_MILLIS)
+            )
+        }
+    }
+
+    @Test
+    fun testOnError_logsFailureResponse() {
+        mSafeCallback.onError(AppFunctionException(AppFunctionException.ERROR_DENIED, "Error: permission denied"))
+
+        ExtendedMockito.verify {
+            AppFunctionsStatsLog.write(
+                /* atomId= */ eq<Int>(AppFunctionsStatsLog.APP_FUNCTIONS_REQUEST_REPORTED),
+                /* callerPackageUid= */ eq<Int>(TEST_CALLING_UID),
+                /* targetPackageUid= */ eq<Int>(TEST_TARGET_UID),
+                /* errorCode= */ eq<Int>(AppFunctionException.ERROR_DENIED),
+                /* requestSizeBytes= */ eq<Int>(mRequestInternal.clientRequest.requestDataSize),
+                /* responseSizeBytes= */ eq<Int>(0),
+                /* requestDurationMs= */ eq<Long>(TEST_EXPECTED_E2E_DURATION_MILLIS),
+                /* requestOverheadMs= */ eq<Long>(TEST_EXPECTED_OVERHEAD_DURATION_MILLIS)
+            )
+        }
+    }
+
+    private companion object {
+        const val TEST_CALLING_PKG = "com.android.trusted.caller"
+        const val TEST_CALLING_UID = 12345
+        const val TEST_TARGET_PACKAGE = "com.android.trusted.target"
+        const val TEST_TARGET_UID = 54321
+        const val TEST_FUNCTION_ID = "com.android.valid.target.doSomething"
+
+        const val TEST_INITIAL_REQUEST_TIME_MILLIS = 10L
+        const val TEST_EXECUTION_TIME_AFTER_BIND_MILLIS = 20L
+        const val TEST_CURRENT_TIME_MILLIS = 50L
+        const val TEST_EXPECTED_E2E_DURATION_MILLIS =
+            TEST_CURRENT_TIME_MILLIS - TEST_INITIAL_REQUEST_TIME_MILLIS
+        const val TEST_EXPECTED_OVERHEAD_DURATION_MILLIS =
+            TEST_EXECUTION_TIME_AFTER_BIND_MILLIS - TEST_INITIAL_REQUEST_TIME_MILLIS
+    }
+}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/BrightnessSynchronizerTest.java b/services/tests/displayservicetests/src/com/android/server/display/BrightnessSynchronizerTest.java
index a8708f9..3449c36 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/BrightnessSynchronizerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/BrightnessSynchronizerTest.java
@@ -224,7 +224,7 @@
         mSynchronizer.startSynchronizing();
         verify(mDisplayManagerMock).registerDisplayListener(mDisplayListenerCaptor.capture(),
                 isA(Handler.class), eq(0L),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         mDisplayListener = mDisplayListenerCaptor.getValue();
 
         verify(mContentResolverSpy).registerContentObserver(eq(BRIGHTNESS_URI), eq(false),
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index a4dfecb..7f12e9c 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -1401,33 +1401,9 @@
     }
 
     @Test
-    public void testRampRateForHdrContent_HdrClamperOff() {
-        float hdrBrightness = 0.8f;
-        float clampedBrightness = 0.6f;
-        float transitionRate = 1.5f;
-
-        DisplayPowerRequest dpr = new DisplayPowerRequest();
-        when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
-        when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(.2f);
-        when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(.1f);
-        when(mHolder.hbmController.getHighBrightnessMode()).thenReturn(
-                BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR);
-        when(mHolder.hbmController.getHdrBrightnessValue()).thenReturn(hdrBrightness);
-        when(mHolder.hdrClamper.getMaxBrightness()).thenReturn(clampedBrightness);
-        when(mHolder.hdrClamper.getTransitionRate()).thenReturn(transitionRate);
-
-        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
-        advanceTime(1); // Run updatePowerState
-
-        verify(mHolder.animator, atLeastOnce()).animateTo(eq(hdrBrightness), anyFloat(),
-                eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE), eq(false));
-    }
-
-    @Test
     public void testRampRateForHdrContent_HdrClamperOn() {
         float clampedBrightness = 0.6f;
         float transitionRate = 1.5f;
-        when(mDisplayManagerFlagsMock.isHdrClamperEnabled()).thenReturn(true);
         mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ true);
 
         DisplayPowerRequest dpr = new DisplayPowerRequest();
@@ -2631,6 +2607,8 @@
         BrightnessClamperController clamperController = mock(BrightnessClamperController.class);
 
         when(hbmController.getCurrentBrightnessMax()).thenReturn(PowerManager.BRIGHTNESS_MAX);
+        when(hdrClamper.clamp(anyFloat())).thenAnswer(
+                invocation -> invocation.getArgument(0));
         when(clamperController.clamp(any(), any(), anyFloat(), anyBoolean(),
                 anyInt())).thenAnswer(
                 invocation -> DisplayBrightnessState.Builder.from(mDisplayBrightnessState)
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt b/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt
index c65024f8..b09947a 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayTopologyCoordinatorTest.kt
@@ -17,7 +17,7 @@
 package com.android.server.display
 
 import android.hardware.display.DisplayTopology
-import android.util.DisplayMetrics
+import android.hardware.display.DisplayTopology.pxToDp
 import android.view.Display
 import android.view.DisplayInfo
 import com.google.common.truth.Truth.assertThat
@@ -62,10 +62,8 @@
     fun addDisplay() {
         coordinator.onDisplayAdded(displayInfo)
 
-        val widthDp = displayInfo.logicalWidth * (DisplayMetrics.DENSITY_DEFAULT.toFloat()
-                / displayInfo.logicalDensityDpi)
-        val heightDp = displayInfo.logicalHeight * (DisplayMetrics.DENSITY_DEFAULT.toFloat()
-                / displayInfo.logicalDensityDpi)
+        val widthDp = pxToDp(displayInfo.logicalWidth.toFloat(), displayInfo.logicalDensityDpi)
+        val heightDp = pxToDp(displayInfo.logicalHeight.toFloat(), displayInfo.logicalDensityDpi)
         verify(mockTopology).addDisplay(displayInfo.displayId, widthDp, heightDp)
         verify(mockTopologyChangedCallback).invoke(mockTopologyCopy)
     }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
index 4e0bab8..f154dbc 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
@@ -1225,8 +1225,8 @@
                 ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
                 any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_CHANGED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener displayListener = displayListenerCaptor.getValue();
 
         setBrightness(10, 10, displayListener);
@@ -1256,8 +1256,8 @@
                 ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
                 any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_CHANGED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener displayListener = displayListenerCaptor.getValue();
 
         setBrightness(10, 10, displayListener);
@@ -1291,8 +1291,8 @@
                 ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
                 any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_CHANGED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener displayListener = displayListenerCaptor.getValue();
 
         setBrightness(10, 10, displayListener);
@@ -1325,8 +1325,8 @@
                   ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
                 any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_CHANGED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener displayListener = displayListenerCaptor.getValue();
 
         ArgumentCaptor<SensorEventListener> sensorListenerCaptor =
@@ -1404,8 +1404,8 @@
                 ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
                 any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_CHANGED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener displayListener = displayListenerCaptor.getValue();
 
         ArgumentCaptor<SensorEventListener> sensorListenerCaptor =
@@ -1464,8 +1464,8 @@
                   ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
                 any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_CHANGED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener displayListener = displayListenerCaptor.getValue();
 
         ArgumentCaptor<SensorEventListener> listenerCaptor =
@@ -1630,8 +1630,8 @@
                 ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
                 any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_CHANGED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener displayListener = displayListenerCaptor.getValue();
 
         // Get the sensor listener so that we can give it new light sensor events
@@ -1730,8 +1730,8 @@
                   ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
                 any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_CHANGED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener displayListener = displayListenerCaptor.getValue();
 
         // Get the sensor listener so that we can give it new light sensor events
@@ -2814,9 +2814,9 @@
                 ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector, times(2)).registerDisplayListener(DisplayCaptor.capture(),
                 any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_ADDED
-                        | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
-                        | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_ADDED
+                        | DisplayManager.EVENT_TYPE_DISPLAY_CHANGED
+                        | DisplayManager.EVENT_TYPE_DISPLAY_REMOVED));
         DisplayListener displayListener = DisplayCaptor.getAllValues().get(0);
 
         // Verify that there is no proximity vote initially
@@ -2877,8 +2877,8 @@
         ArgumentCaptor<DisplayListener> captor =
                   ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_REMOVED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener listener = captor.getValue();
 
         // Specify Limitation
@@ -3000,8 +3000,8 @@
         ArgumentCaptor<DisplayListener> captor =
                   ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_REMOVED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener listener = captor.getValue();
 
         final int initialRefreshRate = 60;
@@ -3075,8 +3075,8 @@
         ArgumentCaptor<DisplayListener> captor =
                   ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_REMOVED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener listener = captor.getValue();
 
         // Specify Limitation for different display
@@ -3115,8 +3115,8 @@
         ArgumentCaptor<DisplayListener> captor =
                   ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_REMOVED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener listener = captor.getValue();
 
         // Specify Limitation
@@ -3200,8 +3200,8 @@
 
         ArgumentCaptor<DisplayListener> captor = ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_REMOVED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener listener = captor.getValue();
 
         // Specify Sunlight limitations
@@ -3239,8 +3239,8 @@
         ArgumentCaptor<DisplayListener> captor =
                   ArgumentCaptor.forClass(DisplayListener.class);
         verify(mInjector).registerDisplayListener(captor.capture(), any(Handler.class),
-                eq(DisplayManager.EVENT_FLAG_DISPLAY_REMOVED),
-                eq(DisplayManager.PRIVATE_EVENT_FLAG_DISPLAY_BRIGHTNESS));
+                eq(DisplayManager.EVENT_TYPE_DISPLAY_REMOVED),
+                eq(DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_BRIGHTNESS));
         DisplayListener listener = captor.getValue();
 
         // Specify Limitation for different display
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
index ea80f28..db6aeeb 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
@@ -602,7 +602,7 @@
         mQueue.dumpDebug(new ProtoOutputStream(),
                 ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
         mQueue.dumpLocked(FileDescriptor.err, new PrintWriter(Writer.nullWriter()),
-                null, 0, true, true, true, null, false);
+                null, 0, true, true, true, null, null, false);
         mQueue.dumpToDropBoxLocked(TAG);
 
         BroadcastQueue.logv(TAG);
@@ -1019,7 +1019,7 @@
             mQueue.dumpDebug(new ProtoOutputStream(),
                     ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
             mQueue.dumpLocked(FileDescriptor.err, new PrintWriter(Writer.nullWriter()),
-                    null, 0, true, true, true, null, false);
+                    null, 0, true, true, true, null, null, false);
         }
 
         waitForIdle();
diff --git a/services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreManagerServiceTest.java
index 76f7e80..0972ea91 100644
--- a/services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/blob/BlobStoreManagerServiceTest.java
@@ -33,7 +33,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.UserHandle;
 import android.platform.test.annotations.Presubmit;
 import android.util.LongSparseArray;
 
@@ -72,6 +71,7 @@
     private static final String TEST_PKG2 = "com.example2";
     private static final String TEST_PKG3 = "com.example3";
 
+    private static final int TEST_USER_ID = 0;
     private static final int TEST_UID1 = 10001;
     private static final int TEST_UID2 = 10002;
     private static final int TEST_UID3 = 10003;
@@ -98,7 +98,7 @@
         mService = new BlobStoreManagerService(mContext, new TestInjector());
         mUserSessions = new LongSparseArray<>();
 
-        mService.addUserSessionsForTest(mUserSessions, UserHandle.myUserId());
+        mService.addUserSessionsForTest(mUserSessions, TEST_USER_ID);
     }
 
     @After
@@ -360,6 +360,7 @@
         return createBlobStoreSessionMock(ownerPackageName, ownerUid, sessionId, sessionFile,
                 mock(BlobHandle.class));
     }
+
     private BlobStoreSession createBlobStoreSessionMock(String ownerPackageName, int ownerUid,
             long sessionId, File sessionFile, BlobHandle blobHandle) {
         final BlobStoreSession session = mock(BlobStoreSession.class);
diff --git a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
index de6f9bd..cd94c0f 100644
--- a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
+++ b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
@@ -391,19 +391,19 @@
                 makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SessionTag.OTHER, creationConfig, new SessionConfig());
+                SessionTag.OTHER, creationConfig, new SessionConfig()).session;
         assertNotNull(a);
 
         creationConfig.tids = SESSION_TIDS_B;
         creationConfig.targetWorkDurationNanos = DOUBLED_TARGET_DURATION;
         IHintSession b = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SessionTag.OTHER, creationConfig, new SessionConfig());
+                SessionTag.OTHER, creationConfig, new SessionConfig()).session;
         assertNotEquals(a, b);
 
         creationConfig.tids = SESSION_TIDS_C;
         creationConfig.targetWorkDurationNanos = 0L;
         IHintSession c = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SessionTag.OTHER, creationConfig, new SessionConfig());
+                SessionTag.OTHER, creationConfig, new SessionConfig()).session;
         assertNotNull(c);
         verify(mNativeWrapperMock, times(3)).halCreateHintSession(anyInt(), anyInt(),
                 any(int[].class), anyLong());
@@ -418,7 +418,7 @@
 
         SessionConfig config = new SessionConfig();
         IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SessionTag.OTHER, creationConfig, config);
+                SessionTag.OTHER, creationConfig, config).session;
         assertNotNull(a);
         assertEquals(SESSION_IDS[0], config.id);
 
@@ -426,7 +426,7 @@
         creationConfig.tids = SESSION_TIDS_B;
         creationConfig.targetWorkDurationNanos = DOUBLED_TARGET_DURATION;
         IHintSession b = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SessionTag.APP, creationConfig, config2);
+                SessionTag.APP, creationConfig, config2).session;
         assertNotEquals(a, b);
         assertEquals(SESSION_IDS[1], config2.id);
 
@@ -434,7 +434,7 @@
         creationConfig.tids = SESSION_TIDS_C;
         creationConfig.targetWorkDurationNanos = 0L;
         IHintSession c = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SessionTag.GAME, creationConfig, config3);
+                SessionTag.GAME, creationConfig, config3).session;
         assertNotNull(c);
         assertEquals(SESSION_IDS[2], config3.id);
         verify(mNativeWrapperMock, times(3)).halCreateHintSessionWithConfig(anyInt(), anyInt(),
@@ -465,16 +465,14 @@
 
         SessionConfig config = new SessionConfig();
         IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SessionTag.OTHER, creationConfig, config);
+                SessionTag.OTHER, creationConfig, config).session;
         assertNotNull(a);
         assertEquals(sessionId1, config.id);
 
         creationConfig.tids = createThreads(1, stopLatch1);
 
-        assertThrows(IllegalArgumentException.class, () -> {
-            service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                    SessionTag.OTHER, creationConfig, config);
-        });
+        assertEquals(service.getBinderServiceInstance().createHintSessionWithConfig(token,
+                    SessionTag.OTHER, creationConfig, config).pipelineThreadLimitExceeded, true);
     }
 
     @Test
@@ -486,7 +484,7 @@
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
 
         // Set session to background and calling updateHintAllowedByProcState() would invoke
         // pause();
@@ -526,7 +524,7 @@
                 makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SessionTag.OTHER, creationConfig, new SessionConfig());
+                SessionTag.OTHER, creationConfig, new SessionConfig()).session;
 
         a.close();
         verify(mNativeWrapperMock, times(1)).halCloseHintSession(anyLong());
@@ -540,16 +538,12 @@
                 makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
 
         IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
-                SessionTag.OTHER, creationConfig, new SessionConfig());
+                SessionTag.OTHER, creationConfig, new SessionConfig()).session;
 
         assertThrows(IllegalArgumentException.class, () -> {
             a.updateTargetWorkDuration(-1L);
         });
 
-        assertThrows(IllegalArgumentException.class, () -> {
-            a.updateTargetWorkDuration(0L);
-        });
-
         a.updateTargetWorkDuration(100L);
         verify(mNativeWrapperMock, times(1)).halUpdateTargetWorkDuration(anyLong(), eq(100L));
     }
@@ -563,7 +557,7 @@
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
 
         a.updateTargetWorkDuration(100L);
         a.reportActualWorkDuration(DURATIONS_THREE, TIMESTAMPS_THREE);
@@ -608,7 +602,7 @@
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
 
         a.sendHint(PerformanceHintManager.Session.CPU_LOAD_RESET);
         verify(mNativeWrapperMock, times(1)).halSendHint(anyLong(),
@@ -637,7 +631,7 @@
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
 
         service.mUidObserver.onUidStateChanged(
                 a.mUid, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND, 0, 0);
@@ -661,7 +655,7 @@
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
 
         service.mUidObserver.onUidStateChanged(
                 a.mUid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0, 0);
@@ -677,7 +671,7 @@
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
 
         a.updateTargetWorkDuration(100L);
 
@@ -717,7 +711,7 @@
                 makeSessionCreationConfig(tids1, DEFAULT_TARGET_DURATION);
         AppHintSession session1 = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
         assertNotNull(session1);
 
         // trigger UID state change by making the process foreground->background, but because the
@@ -754,7 +748,7 @@
                 makeSessionCreationConfig(tids1, DEFAULT_TARGET_DURATION);
         AppHintSession session1 = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
         assertNotNull(session1);
 
         // let all session 1 threads to exit and the cleanup should force pause the session 1
@@ -865,7 +859,7 @@
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
 
         a.setMode(0, true);
         verify(mNativeWrapperMock, times(1)).halSetMode(anyLong(),
@@ -885,7 +879,7 @@
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
 
         // Set session to background, then the duration would not be updated.
         service.mUidObserver.onUidStateChanged(
@@ -906,7 +900,7 @@
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
 
         assertThrows(IllegalArgumentException.class, () -> {
             a.setMode(-1, true);
@@ -923,7 +917,7 @@
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
         assertNotNull(a);
         verify(mNativeWrapperMock, times(1)).halSetMode(anyLong(),
                 eq(0), eq(true));
@@ -1124,7 +1118,7 @@
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
         // we will start some threads and get their valid TIDs to update
         int threadCount = 3;
         // the list of TIDs
@@ -1194,7 +1188,7 @@
 
         AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
                 .createHintSessionWithConfig(token, SessionTag.OTHER,
-                        creationConfig, new SessionConfig());
+                        creationConfig, new SessionConfig()).session;
 
         a.updateTargetWorkDuration(100L);
         a.reportActualWorkDuration2(WORK_DURATIONS_FIVE);
@@ -1417,7 +1411,6 @@
         halParams3.tids = tids;
         halParams3.calculationType = CpuHeadroomParams.CalculationType.AVERAGE;
 
-        // this params should not be cached as the window is not default
         CpuHeadroomParamsInternal params4 = new CpuHeadroomParamsInternal();
         params4.calculationWindowMillis = 123;
         CpuHeadroomParams halParams4 = new CpuHeadroomParams();
@@ -1456,11 +1449,7 @@
         assertEquals(halRet2, service.getBinderServiceInstance().getCpuHeadroom(params2));
         assertEquals(halRet3, service.getBinderServiceInstance().getCpuHeadroom(params3));
         assertEquals(halRet4, service.getBinderServiceInstance().getCpuHeadroom(params4));
-        verify(mIPowerMock, times(1)).getCpuHeadroom(any());
-        verify(mIPowerMock, times(0)).getCpuHeadroom(eq(halParams1));
-        verify(mIPowerMock, times(0)).getCpuHeadroom(eq(halParams2));
-        verify(mIPowerMock, times(0)).getCpuHeadroom(eq(halParams3));
-        verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams4));
+        verify(mIPowerMock, times(0)).getCpuHeadroom(any());
 
         // after 500ms more it should be served with cache
         Thread.sleep(500);
@@ -1469,11 +1458,7 @@
         assertEquals(halRet2, service.getBinderServiceInstance().getCpuHeadroom(params2));
         assertEquals(halRet3, service.getBinderServiceInstance().getCpuHeadroom(params3));
         assertEquals(halRet4, service.getBinderServiceInstance().getCpuHeadroom(params4));
-        verify(mIPowerMock, times(1)).getCpuHeadroom(any());
-        verify(mIPowerMock, times(0)).getCpuHeadroom(eq(halParams1));
-        verify(mIPowerMock, times(0)).getCpuHeadroom(eq(halParams2));
-        verify(mIPowerMock, times(0)).getCpuHeadroom(eq(halParams3));
-        verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams4));
+        verify(mIPowerMock, times(0)).getCpuHeadroom(any());
 
         // after 1+ seconds it should be served from HAL as it exceeds 1000 millis interval
         Thread.sleep(600);
@@ -1580,18 +1565,14 @@
         clearInvocations(mIPowerMock);
         assertEquals(halRet1, service.getBinderServiceInstance().getGpuHeadroom(params1));
         assertEquals(halRet2, service.getBinderServiceInstance().getGpuHeadroom(params2));
-        verify(mIPowerMock, times(1)).getGpuHeadroom(any());
-        verify(mIPowerMock, times(0)).getGpuHeadroom(eq(halParams1));
-        verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams2));
+        verify(mIPowerMock, times(0)).getGpuHeadroom(any());
 
         // after 500ms it should be served with cache
         Thread.sleep(500);
         clearInvocations(mIPowerMock);
         assertEquals(halRet1, service.getBinderServiceInstance().getGpuHeadroom(params1));
         assertEquals(halRet2, service.getBinderServiceInstance().getGpuHeadroom(params2));
-        verify(mIPowerMock, times(1)).getGpuHeadroom(any());
-        verify(mIPowerMock, times(0)).getGpuHeadroom(eq(halParams1));
-        verify(mIPowerMock, times(1)).getGpuHeadroom(eq(halParams2));
+        verify(mIPowerMock, times(0)).getGpuHeadroom(any());
 
         // after 1+ seconds it should be served from HAL as it exceeds 1000 millis interval
         Thread.sleep(600);
diff --git a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
index 71a2651..45761b6 100644
--- a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
@@ -1697,6 +1697,46 @@
     }
 
     /**
+     * If processPowerKeyDown is called instead of interceptPowerKeyDown (meaning the double tap
+     * gesture isn't performed), the emergency gesture is still launched.
+     */
+    @Test
+    public void testProcessPowerKeyDown_fiveInboundPresses_emergencyGestureLaunches() {
+        enableCameraGesture();
+        enableEmergencyGesture();
+
+        // First event
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, false, false);
+
+        //Second event; call processPowerKeyDown without calling interceptPowerKeyDown
+        final long interval = POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+        eventTime += interval;
+        KeyEvent keyEvent =
+                new KeyEvent(
+                        IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, IGNORED_REPEAT);
+        mGestureLauncherService.processPowerKeyDown(keyEvent);
+
+        verify(mMetricsLogger, never())
+                .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
+
+        // Presses 3 and 4 should not trigger any gesture
+        for (int i = 0; i < 2; i++) {
+            eventTime += interval;
+            sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, false);
+        }
+
+        // Fifth button press should still trigger the emergency flow
+        eventTime += interval;
+        sendPowerKeyDownToGestureLauncherServiceAndAssertValues(eventTime, true, true);
+
+        verify(mUiEventLogger, times(1))
+                .log(GestureLauncherService.GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER);
+        verify(mStatusBarManagerInternal).onEmergencyActionLaunchGestureDetected();
+    }
+
+    /**
      * Helper method to trigger emergency gesture by pressing button for 5 times.
      *
      * @return last event time.
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 0b2a2cd..4e030d4 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -2045,18 +2045,6 @@
         return p == null ? null : p.getAllShareTargetsForTest();
     }
 
-    protected void resetPersistedShortcuts() {
-        final ShortcutPackage p = mService.getPackageShortcutForTest(
-                getCallingPackage(), getCallingUserId());
-        p.removeAllShortcutsAsync();
-    }
-
-    protected void getPersistedShortcut(AndroidFuture<List<ShortcutInfo>> cb) {
-        final ShortcutPackage p = mService.getPackageShortcutForTest(
-                getCallingPackage(), getCallingUserId());
-        p.getTopShortcutsFromPersistence(cb);
-    }
-
     /**
      * @return the number of shortcuts stored internally for the caller that can be used as a share
      * target in the ShareSheet. Such shortcuts have a matching category with at least one of the
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java
deleted file mode 100644
index 10e8bf0..0000000
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.pm;
-
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
-
-import android.app.PendingIntent;
-import android.content.pm.ShortcutInfo;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-
-import com.android.internal.infra.AndroidFuture;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-/**
- * Tests for {@link android.app.appsearch.AppSearchManager} and relevant APIs in ShortcutManager.
- *
- atest -c com.android.server.pm.ShortcutManagerTest12
- */
-public class ShortcutManagerTest12 extends BaseShortcutManagerTest {
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mService.updateConfigurationLocked(
-                ShortcutService.ConfigConstants.KEY_MAX_SHORTCUTS + "=5,"
-                        + ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=1");
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (mService.isAppSearchEnabled()) {
-            setCaller(CALLING_PACKAGE_1, USER_10);
-            mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_10)
-                    .removeAllShortcutsAsync();
-        }
-        super.tearDown();
-    }
-
-    public void testGetShortcutIntents_ReturnsMutablePendingIntents() throws RemoteException {
-        setDefaultLauncher(USER_10, LAUNCHER_1);
-
-        runWithCaller(CALLING_PACKAGE_1, USER_10, () ->
-                assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))))
-        );
-
-        runWithCaller(LAUNCHER_1, USER_10, () -> {
-            final PendingIntent intent = mLauncherApps.getShortcutIntent(
-                    CALLING_PACKAGE_1, "s1", null, UserHandle.SYSTEM);
-            assertNotNull(intent);
-        });
-    }
-
-    public void testSetDynamicShortcuts_PersistsShortcutsToDisk() throws RemoteException {
-        if (!mService.isAppSearchEnabled()) {
-            return;
-        }
-        setCaller(CALLING_PACKAGE_1, USER_10);
-        // Verifies setDynamicShortcuts persists shortcuts into AppSearch
-        mManager.setDynamicShortcuts(list(
-                makeShortcut("s1"),
-                makeShortcut("s2"),
-                makeShortcut("s3")
-        ));
-        List<ShortcutInfo> shortcuts = getAllPersistedShortcuts();
-        assertNotNull(shortcuts);
-        assertEquals(3, shortcuts.size());
-        Set<String> shortcutIds =
-                shortcuts.stream().map(ShortcutInfo::getId).collect(Collectors.toSet());
-        assertTrue(shortcutIds.contains("s1"));
-        assertTrue(shortcutIds.contains("s2"));
-        assertTrue(shortcutIds.contains("s3"));
-
-        // Verifies removeAllDynamicShortcuts removes shortcuts from persistence layer
-        mManager.removeAllDynamicShortcuts();
-        shortcuts = getAllPersistedShortcuts();
-        assertNotNull(shortcuts);
-        assertTrue(shortcuts.isEmpty());
-    }
-
-    public void testAddDynamicShortcuts_PersistsShortcutsToDisk() {
-        if (!mService.isAppSearchEnabled()) {
-            return;
-        }
-        setCaller(CALLING_PACKAGE_1, USER_10);
-        mManager.setDynamicShortcuts(list(
-                makeShortcut("s1"),
-                makeShortcut("s2"),
-                makeShortcut("s3")
-        ));
-        // Verifies addDynamicShortcuts persists shortcuts into AppSearch
-        mManager.addDynamicShortcuts(list(makeShortcut("s4"), makeShortcut("s5")));
-        final List<ShortcutInfo> shortcuts = getAllPersistedShortcuts();
-        assertNotNull(shortcuts);
-        assertEquals(5, shortcuts.size());
-        final Set<String> shortcutIds =
-                shortcuts.stream().map(ShortcutInfo::getId).collect(Collectors.toSet());
-        assertTrue(shortcutIds.contains("s1"));
-        assertTrue(shortcutIds.contains("s2"));
-        assertTrue(shortcutIds.contains("s3"));
-        assertTrue(shortcutIds.contains("s4"));
-        assertTrue(shortcutIds.contains("s5"));
-    }
-
-    public void testPushDynamicShortcuts_PersistsShortcutsToDisk() {
-        if (!mService.isAppSearchEnabled()) {
-            return;
-        }
-        setCaller(CALLING_PACKAGE_1, USER_10);
-        mManager.setDynamicShortcuts(list(
-                makeShortcut("s1"),
-                makeShortcut("s2"),
-                makeShortcut("s3"),
-                makeShortcut("s4"),
-                makeShortcut("s5")
-        ));
-        List<ShortcutInfo> shortcuts = getAllPersistedShortcuts();
-        assertNotNull(shortcuts);
-        assertEquals(5, shortcuts.size());
-        Set<String> shortcutIds =
-                shortcuts.stream().map(ShortcutInfo::getId).collect(Collectors.toSet());
-        assertTrue(shortcutIds.contains("s1"));
-        assertTrue(shortcutIds.contains("s2"));
-        assertTrue(shortcutIds.contains("s3"));
-        assertTrue(shortcutIds.contains("s4"));
-        assertTrue(shortcutIds.contains("s5"));
-        // Verifies pushDynamicShortcuts further persists shortcuts into AppSearch without
-        // removing previous shortcuts when max number of shortcuts is reached.
-        mManager.pushDynamicShortcut(makeShortcut("s6"));
-        // Increasing the max number of shortcuts since number of results per page in AppSearch
-        // is set to match the former.
-        mService.updateConfigurationLocked(
-                ShortcutService.ConfigConstants.KEY_MAX_SHORTCUTS + "=10,"
-                        + ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=1");
-        shortcuts = getAllPersistedShortcuts();
-        assertNotNull(shortcuts);
-        assertEquals(6, shortcuts.size());
-        shortcutIds = shortcuts.stream().map(ShortcutInfo::getId).collect(Collectors.toSet());
-        assertTrue(shortcutIds.contains("s1"));
-        assertTrue(shortcutIds.contains("s2"));
-        assertTrue(shortcutIds.contains("s3"));
-        assertTrue(shortcutIds.contains("s4"));
-        assertTrue(shortcutIds.contains("s5"));
-        assertTrue(shortcutIds.contains("s6"));
-    }
-
-    public void testRemoveDynamicShortcuts_RemovesShortcutsFromDisk() {
-        if (!mService.isAppSearchEnabled()) {
-            return;
-        }
-        setCaller(CALLING_PACKAGE_1, USER_10);
-        mManager.setDynamicShortcuts(list(
-                makeShortcut("s1"),
-                makeShortcut("s2"),
-                makeShortcut("s3"),
-                makeShortcut("s4"),
-                makeShortcut("s5")
-        ));
-
-        // Verifies removeDynamicShortcuts removes shortcuts from persistence layer
-        mManager.removeDynamicShortcuts(list("s1"));
-        final List<ShortcutInfo> shortcuts = getAllPersistedShortcuts();
-        assertNotNull(shortcuts);
-        assertEquals(4, shortcuts.size());
-        final Set<String> shortcutIds =
-                shortcuts.stream().map(ShortcutInfo::getId).collect(Collectors.toSet());
-        assertTrue(shortcutIds.contains("s2"));
-        assertTrue(shortcutIds.contains("s3"));
-        assertTrue(shortcutIds.contains("s4"));
-        assertTrue(shortcutIds.contains("s5"));
-    }
-
-    public void testRemoveLongLivedShortcuts_RemovesShortcutsFromDisk() {
-        if (!mService.isAppSearchEnabled()) {
-            return;
-        }
-        setCaller(CALLING_PACKAGE_1, USER_10);
-        mManager.setDynamicShortcuts(list(
-                makeShortcut("s1"),
-                makeShortcut("s2"),
-                makeShortcut("s3"),
-                makeShortcut("s4"),
-                makeShortcut("s5")
-        ));
-        mManager.removeDynamicShortcuts(list("s2"));
-        final List<ShortcutInfo> shortcuts = getAllPersistedShortcuts();
-        assertNotNull(shortcuts);
-        assertEquals(4, shortcuts.size());
-        final Set<String> shortcutIds =
-                shortcuts.stream().map(ShortcutInfo::getId).collect(Collectors.toSet());
-        assertTrue(shortcutIds.contains("s1"));
-        assertTrue(shortcutIds.contains("s3"));
-        assertTrue(shortcutIds.contains("s4"));
-        assertTrue(shortcutIds.contains("s5"));
-    }
-
-    public void testDisableShortcuts_RemovesShortcutsFromDisk() {
-        if (!mService.isAppSearchEnabled()) {
-            return;
-        }
-        setCaller(CALLING_PACKAGE_1, USER_10);
-        mManager.setDynamicShortcuts(list(
-                makeShortcut("s1"),
-                makeShortcut("s2"),
-                makeShortcut("s3"),
-                makeShortcut("s4"),
-                makeShortcut("s5")
-        ));
-        // Verifies disableShortcuts removes shortcuts from persistence layer
-        mManager.disableShortcuts(list("s3"));
-        final List<ShortcutInfo> shortcuts = getAllPersistedShortcuts();
-        assertNotNull(shortcuts);
-        assertEquals(4, shortcuts.size());
-        final Set<String> shortcutIds =
-                shortcuts.stream().map(ShortcutInfo::getId).collect(Collectors.toSet());
-        assertTrue(shortcutIds.contains("s1"));
-        assertTrue(shortcutIds.contains("s2"));
-        assertTrue(shortcutIds.contains("s4"));
-        assertTrue(shortcutIds.contains("s5"));
-    }
-
-    public void testUpdateShortcuts_UpdateShortcutsOnDisk() {
-        if (!mService.isAppSearchEnabled()) {
-            return;
-        }
-        setCaller(CALLING_PACKAGE_1, USER_10);
-        mManager.setDynamicShortcuts(list(
-                makeShortcut("s1"),
-                makeShortcut("s2"),
-                makeShortcut("s3"),
-                makeShortcut("s4"),
-                makeShortcut("s5")
-        ));
-        // Verifies disableShortcuts removes shortcuts from persistence layer
-        mManager.updateShortcuts(list(makeShortcutWithShortLabel("s3", "custom")));
-        final List<ShortcutInfo> shortcuts = getAllPersistedShortcuts();
-        assertNotNull(shortcuts);
-        assertEquals(5, shortcuts.size());
-        final Map<String, ShortcutInfo> map = shortcuts.stream()
-                .collect(Collectors.toMap(ShortcutInfo::getId, Function.identity()));
-        assertTrue(map.containsKey("s3"));
-        assertEquals("custom", map.get("s3").getShortLabel());
-    }
-
-    public void testShortcutsExcludedFromLauncher_PersistedToDisk() {
-        if (!mService.isAppSearchEnabled()) {
-            return;
-        }
-        setCaller(CALLING_PACKAGE_1, USER_10);
-        mManager.setDynamicShortcuts(list(
-                makeShortcutExcludedFromLauncher("s1"),
-                makeShortcutExcludedFromLauncher("s2"),
-                makeShortcutExcludedFromLauncher("s3"),
-                makeShortcutExcludedFromLauncher("s4"),
-                makeShortcutExcludedFromLauncher("s5")
-        ));
-        final List<ShortcutInfo> shortcuts = getAllPersistedShortcuts();
-        assertNotNull(shortcuts);
-        assertEquals(5, shortcuts.size());
-        final Map<String, ShortcutInfo> map = shortcuts.stream()
-                .collect(Collectors.toMap(ShortcutInfo::getId, Function.identity()));
-        assertTrue(map.containsKey("s3"));
-        assertEquals("Title-s3", map.get("s3").getShortLabel());
-    }
-
-
-    private List<ShortcutInfo> getAllPersistedShortcuts() {
-        try {
-            SystemClock.sleep(5000);
-            final AndroidFuture<List<ShortcutInfo>> future = new AndroidFuture<>();
-            getPersistedShortcut(future);
-            return future.get(10, TimeUnit.SECONDS);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java b/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
index c7a06b8..b1df0f1 100644
--- a/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
@@ -31,7 +31,6 @@
 import android.os.test.TestLooper;
 import android.provider.Settings;
 import android.security.advancedprotection.AdvancedProtectionFeature;
-import android.security.advancedprotection.AdvancedProtectionManager;
 import android.security.advancedprotection.IAdvancedProtectionCallback;
 
 import androidx.annotation.NonNull;
@@ -55,8 +54,7 @@
     private Context mContext;
     private AdvancedProtectionService.AdvancedProtectionStore mStore;
     private TestLooper mLooper;
-    AdvancedProtectionFeature mTestFeature2g = new AdvancedProtectionFeature(
-            AdvancedProtectionManager.FEATURE_ID_DISALLOW_CELLULAR_2G);
+    AdvancedProtectionFeature mFeature = new AdvancedProtectionFeature("test-id");
 
     @Before
     public void setup() throws Settings.SettingNotFoundException {
@@ -107,7 +105,7 @@
                     @NonNull
                     @Override
                     public AdvancedProtectionFeature getFeature() {
-                        return mTestFeature2g;
+                        return mFeature;
                     }
 
                     @Override
@@ -137,7 +135,7 @@
                     @NonNull
                     @Override
                     public AdvancedProtectionFeature getFeature() {
-                        return mTestFeature2g;
+                        return mFeature;
                     }
 
                     @Override
@@ -167,7 +165,7 @@
                     @NonNull
                     @Override
                     public AdvancedProtectionFeature getFeature() {
-                        return mTestFeature2g;
+                        return mFeature;
                     }
 
                     @Override
@@ -240,10 +238,8 @@
 
     @Test
     public void testGetFeatures() {
-        AdvancedProtectionFeature feature1 = new AdvancedProtectionFeature(
-                AdvancedProtectionManager.FEATURE_ID_DISALLOW_CELLULAR_2G);
-        AdvancedProtectionFeature feature2 = new AdvancedProtectionFeature(
-                AdvancedProtectionManager.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES);
+        AdvancedProtectionFeature feature1 = new AdvancedProtectionFeature("id-1");
+        AdvancedProtectionFeature feature2 = new AdvancedProtectionFeature("id-2");
         AdvancedProtectionHook hook = new AdvancedProtectionHook(mContext, true) {
             @NonNull
             @Override
@@ -272,10 +268,8 @@
 
     @Test
     public void testGetFeatures_featureNotAvailable() {
-        AdvancedProtectionFeature feature1 = new AdvancedProtectionFeature(
-                AdvancedProtectionManager.FEATURE_ID_DISALLOW_CELLULAR_2G);
-        AdvancedProtectionFeature feature2 = new AdvancedProtectionFeature(
-                AdvancedProtectionManager.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES);
+        AdvancedProtectionFeature feature1 = new AdvancedProtectionFeature("id-1");
+        AdvancedProtectionFeature feature2 = new AdvancedProtectionFeature("id-2");
         AdvancedProtectionHook hook = new AdvancedProtectionHook(mContext, true) {
             @NonNull
             @Override
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
index d1dc8d6..4f5cdb7 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
@@ -19,9 +19,13 @@
 import static android.service.notification.Adjustment.KEY_IMPORTANCE;
 import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION;
 import static android.service.notification.Adjustment.TYPE_NEWS;
+import static android.service.notification.Adjustment.TYPE_OTHER;
 import static android.service.notification.Adjustment.TYPE_PROMOTION;
+import static android.service.notification.Adjustment.TYPE_SOCIAL_MEDIA;
+import static android.service.notification.Flags.notificationClassification;
 
 import static com.android.server.notification.NotificationManagerService.DEFAULT_ALLOWED_ADJUSTMENTS;
+import static com.android.server.notification.NotificationManagerService.DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -144,6 +148,17 @@
         mAssistants.readXml(parser, mNm::canUseManagedServices, false, USER_ALL);
     }
 
+    private void setDefaultAllowedAdjustmentKeyTypes(NotificationAssistants assistants) {
+        assistants.setAssistantAdjustmentKeyTypeState(TYPE_OTHER, false);
+        assistants.setAssistantAdjustmentKeyTypeState(TYPE_PROMOTION, false);
+        assistants.setAssistantAdjustmentKeyTypeState(TYPE_SOCIAL_MEDIA, false);
+        assistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, false);
+        assistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, false);
+
+        for (int type : DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES) {
+            assistants.setAssistantAdjustmentKeyTypeState(type, true);
+        }
+    }
 
     @Before
     public void setUp() throws Exception {
@@ -154,6 +169,9 @@
                 com.android.internal.R.string.config_defaultAssistantAccessComponent,
                 mCn.flattenToString());
         mAssistants = spy(mNm.new NotificationAssistants(mContext, mLock, mUserProfiles, miPm));
+        if (notificationClassification()) {
+            setDefaultAllowedAdjustmentKeyTypes(mAssistants);
+        }
         when(mNm.getBinderService()).thenReturn(mINm);
         mContext.ensureTestableResources();
 
@@ -695,7 +713,7 @@
         mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, true);
 
         assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList()
-                .containsExactlyElementsIn(List.of(TYPE_PROMOTION, TYPE_CONTENT_RECOMMENDATION));
+                .containsExactly(TYPE_PROMOTION, TYPE_CONTENT_RECOMMENDATION);
     }
 
     @Test
@@ -716,7 +734,7 @@
         writeXmlAndReload(USER_ALL);
 
         assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList()
-                .containsExactlyElementsIn(List.of(TYPE_NEWS, TYPE_CONTENT_RECOMMENDATION));
+                .containsExactly(TYPE_NEWS, TYPE_CONTENT_RECOMMENDATION);
     }
 
     @Test
@@ -732,76 +750,146 @@
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
-    public void testSetAssistantAdjustmentKeyTypeStateForPackage_allowsAndDenies() {
-        // Given that a package is allowed to have its type adjusted,
-        String allowedPackage = "allowed.package";
-        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty();
-        mAssistants.setTypeAdjustmentForPackageState(allowedPackage, true);
-
-        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty();
-        assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage));
-
-        // Set type adjustment disallowed for this package
-        mAssistants.setTypeAdjustmentForPackageState(allowedPackage, false);
-
-        // Then the package is marked as denied
-        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList()
-                .containsExactly(allowedPackage);
-        assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage));
-
-        // Set type adjustment allowed again
-        mAssistants.setTypeAdjustmentForPackageState(allowedPackage, true);
-
-        // Then the package is marked as allowed again
-        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty();
-        assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage));
+    public void testSetAssistantAdjustmentKeyTypeStateForPackage_usesGlobalDefault() {
+        String pkg = "my.package";
+        setDefaultAllowedAdjustmentKeyTypes(mAssistants);
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_PROMOTION)).isTrue();
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isFalse();
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList()
+                .containsExactlyElementsIn(DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES);
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
-    public void testSetAssistantAdjustmentKeyTypeStateForPackage_deniesMultiple() {
-        // Given packages not allowed to have their type adjusted,
-        String deniedPkg1 = "denied.Pkg1";
-        String deniedPkg2 = "denied.Pkg2";
-        String deniedPkg3 = "denied.Pkg3";
-        // Set type adjustment disallowed for these packages
-        mAssistants.setTypeAdjustmentForPackageState(deniedPkg1, false);
-        mAssistants.setTypeAdjustmentForPackageState(deniedPkg2, false);
-        mAssistants.setTypeAdjustmentForPackageState(deniedPkg3, false);
+    public void testSetAssistantAdjustmentKeyTypeStateForPackage_allowsAndDenies() {
+        setDefaultAllowedAdjustmentKeyTypes(mAssistants);
+        // Given that a package is set to have a type adjustment allowed,
+        String pkg = "my.package";
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_NEWS, true);
 
-        // Then the packages are marked as denied
-        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList()
-                .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg2, deniedPkg3));
-        assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg1));
-        assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg2));
-        assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg3));
+        // The newly set state is the combination of the global default and the newly set type.
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList()
+                .containsExactly(TYPE_NEWS, TYPE_PROMOTION);
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue();
 
-        // And when we re-allow one of them,
-        mAssistants.setTypeAdjustmentForPackageState(deniedPkg2, true);
+        // Set type adjustment disallowed for this package
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_NEWS, false);
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_PROMOTION, false);
 
-        // Then the rest of the original packages are still marked as denied.
-        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList()
-                .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg3));
-        assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg1));
-        assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg2));
-        assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg3));
+        // Then the package is marked as denied
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).isEmpty();
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isFalse();
+
+        // Set type adjustment allowed again
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_NEWS, true);
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_PROMOTION, true);
+
+        // Then the package is marked as allowed again
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList()
+                .containsExactly(TYPE_NEWS, TYPE_PROMOTION);
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue();
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_PROMOTION)).isTrue();
+
+        // Set type adjustment promotions false,
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_PROMOTION, false);
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList()
+                .containsExactly(TYPE_NEWS);
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue();
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_PROMOTION)).isFalse();
+    }
+
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+    public void testSetAssistantAdjustmentKeyTypeStateForPackage_allowsMultiplePkgs() {
+        setDefaultAllowedAdjustmentKeyTypes(mAssistants);
+        // Given packages allowed to have their type adjusted to  TYPE_NEWS,
+        String allowedPkg1 = "allowed.Pkg1";
+        String allowedPkg2 = "allowed.Pkg2";
+        String allowedPkg3 = "allowed.Pkg3";
+        // Set type adjustment allowed for these packages
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg1, TYPE_NEWS, true);
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg2, TYPE_NEWS, true);
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg3, TYPE_NEWS, true);
+
+        // The newly set state is the combination of the global default and the newly set type.
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg1)).asList()
+                .containsExactly(TYPE_NEWS, TYPE_PROMOTION);
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg2)).asList()
+                .containsExactly(TYPE_NEWS, TYPE_PROMOTION);
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg3)).asList()
+                .containsExactly(TYPE_NEWS, TYPE_PROMOTION);
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg1, TYPE_NEWS)).isTrue();
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg2, TYPE_NEWS)).isTrue();
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg3, TYPE_NEWS)).isTrue();
+
+        // And when we deny some of them,
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg2, TYPE_NEWS, false);
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg2, TYPE_PROMOTION,
+                false);
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg3, TYPE_PROMOTION,
+                false);
+
+        // Then the rest of the original packages are still marked as allowed.
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg1)).asList()
+                .containsExactly(TYPE_NEWS, TYPE_PROMOTION);
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg2)).isEmpty();
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg3)).asList()
+                .containsExactly(TYPE_NEWS);
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg1, TYPE_NEWS)).isTrue();
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg2, TYPE_NEWS)).isFalse();
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg3, TYPE_NEWS)).isTrue();
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
     public void testSetAssistantAdjustmentKeyTypeStateForPackage_readWriteXml() throws Exception {
+        setDefaultAllowedAdjustmentKeyTypes(mAssistants);
         mAssistants.loadDefaultsFromConfig(true);
         String deniedPkg1 = "denied.Pkg1";
         String allowedPkg2 = "allowed.Pkg2";
-        String deniedPkg3 = "denied.Pkg3";
+        String allowedPkg3 = "allowed.Pkg3";
         // Set type adjustment disallowed or allowed for these packages
-        mAssistants.setTypeAdjustmentForPackageState(deniedPkg1, false);
-        mAssistants.setTypeAdjustmentForPackageState(allowedPkg2, true);
-        mAssistants.setTypeAdjustmentForPackageState(deniedPkg3, false);
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(deniedPkg1, TYPE_PROMOTION, false);
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg2, TYPE_NEWS, true);
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg3, TYPE_NEWS, true);
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg3, TYPE_SOCIAL_MEDIA,
+                true);
 
         writeXmlAndReload(USER_ALL);
 
-        assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList()
-                .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg3));
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(deniedPkg1)).isEmpty();
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg2)).asList()
+                .containsExactly(TYPE_NEWS, TYPE_PROMOTION);
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg3)).asList()
+                .containsExactly(TYPE_NEWS, TYPE_SOCIAL_MEDIA, TYPE_PROMOTION);
+    }
+
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
+    public void testSetAssistantAdjustmentKeyTypeStateForPackage_noGlobalImpact() throws Exception {
+        setDefaultAllowedAdjustmentKeyTypes(mAssistants);
+        // When the global state is changed,
+        mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, true);
+
+        // The package state reflects the global state.
+        String pkg = "my.package";
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_PROMOTION)).isTrue();
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue();
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList()
+                .containsExactly(TYPE_NEWS, TYPE_PROMOTION);
+
+        // Once the package specific state is modified,
+        mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_SOCIAL_MEDIA, true);
+
+        // The package specific state combines the global state with those modifications
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_SOCIAL_MEDIA)).isTrue();
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList()
+                .containsExactly(TYPE_NEWS, TYPE_PROMOTION, TYPE_SOCIAL_MEDIA);
+
+        // And further changes to the global state are ignored.
+        mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, false);
+        assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue();
+        assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList()
+                .containsExactly(TYPE_NEWS, TYPE_PROMOTION, TYPE_SOCIAL_MEDIA);
     }
 }
\ No newline at end of file
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 601023f..301165f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -365,6 +365,9 @@
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
@@ -380,9 +383,6 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.function.Consumer;
 
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
-import platform.test.runner.parameterized.Parameters;
-
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4.class)
 @RunWithLooper
@@ -644,6 +644,9 @@
         doNothing().when(mContext).sendBroadcast(any(), anyString());
         doNothing().when(mContext).sendBroadcastAsUser(any(), any());
         doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());
+        doNothing().when(mContext).sendBroadcastMultiplePermissions(any(), any(), any(), any());
+        doReturn(mContext).when(mContext).createContextAsUser(eq(mUser), anyInt());
+
         TestableContentResolver cr = mock(TestableContentResolver.class);
         when(mContext.getContentResolver()).thenReturn(cr);
         doNothing().when(cr).registerContentObserver(any(), anyBoolean(), any(), anyInt());
@@ -7631,7 +7634,7 @@
         when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
         when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true);
         when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
-        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true);
+        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true);
 
         // Set up notifications that will be adjusted
         final NotificationRecord r1 = spy(generateNotificationRecord(
@@ -11235,7 +11238,8 @@
     }
 
     @Test
-    public void onZenModeChanged_sendsBroadcasts() throws Exception {
+    @DisableFlags(Flags.FLAG_NM_BINDER_PERF_REDUCE_ZEN_BROADCASTS)
+    public void onZenModeChanged_sendsBroadcasts_oldBehavior() throws Exception {
         when(mAmi.getCurrentUserId()).thenReturn(100);
         when(mUmInternal.getProfileIds(eq(100), anyBoolean())).thenReturn(new int[]{100, 101, 102});
         when(mConditionProviders.getAllowedPackages(anyInt())).then(new Answer<List<String>>() {
@@ -11288,6 +11292,74 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_REDUCE_ZEN_BROADCASTS)
+    public void onZenModeChanged_sendsBroadcasts() throws Exception {
+        when(mAmi.getCurrentUserId()).thenReturn(100);
+        when(mUmInternal.getProfileIds(eq(100), anyBoolean())).thenReturn(new int[]{100, 101, 102});
+        when(mConditionProviders.getAllowedPackages(anyInt())).then(new Answer<List<String>>() {
+            @Override
+            public List<String> answer(InvocationOnMock invocation) {
+                int userId = invocation.getArgument(0);
+                switch (userId) {
+                    case 100:
+                        return Lists.newArrayList("a", "b", "c");
+                    case 101:
+                        return Lists.newArrayList();
+                    case 102:
+                        return Lists.newArrayList("b");
+                    default:
+                        throw new IllegalArgumentException(
+                                "Why would you ask for packages of userId " + userId + "?");
+                }
+            }
+        });
+        Context context100 = mock(Context.class);
+        doReturn(context100).when(mContext).createContextAsUser(eq(UserHandle.of(100)), anyInt());
+        Context context101 = mock(Context.class);
+        doReturn(context101).when(mContext).createContextAsUser(eq(UserHandle.of(101)), anyInt());
+        Context context102 = mock(Context.class);
+        doReturn(context102).when(mContext).createContextAsUser(eq(UserHandle.of(102)), anyInt());
+
+        mService.getBinderService().setZenMode(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS, null,
+                "testing!", false);
+        waitForIdle();
+
+        // Verify broadcasts per user: registered receivers first, then DND packages.
+        InOrder inOrder = inOrder(context100, context101, context102);
+
+        inOrder.verify(context100).sendBroadcastMultiplePermissions(
+                eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+                        .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)),
+                eq(new String[0]), eq(new String[0]), eq(new String[] {"a", "b", "c"}));
+        inOrder.verify(context100).sendBroadcast(
+                eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+                        .setPackage("a")
+                        .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)));
+        inOrder.verify(context100).sendBroadcast(
+                eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+                        .setPackage("b")
+                        .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)));
+        inOrder.verify(context100).sendBroadcast(
+                eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+                        .setPackage("c")
+                        .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)));
+
+        inOrder.verify(context101).sendBroadcastMultiplePermissions(
+                eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+                        .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)),
+                eq(new String[0]), eq(new String[0]), eq(new String[] {}));
+
+        inOrder.verify(context102).sendBroadcastMultiplePermissions(
+                eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+                        .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)),
+                eq(new String[0]), eq(new String[0]), eq(new String[] {"b"}));
+        inOrder.verify(context102).sendBroadcast(
+                eqIntent(new Intent(ACTION_INTERRUPTION_FILTER_CHANGED)
+                        .setPackage("b")
+                        .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)));
+    }
+
+    @Test
     @EnableFlags(android.app.Flags.FLAG_MODES_API)
     public void onAutomaticRuleStatusChanged_sendsBroadcastToRuleOwner() throws Exception {
         mService.mZenModeHelper.getCallbacks().forEach(c -> c.onAutomaticRuleStatusChanged(
@@ -17305,7 +17377,7 @@
                 NotificationManagerService.WorkerHandler.class);
         mService.setHandler(handler);
         when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
-        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true);
+        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true);
 
         Bundle signals = new Bundle();
         signals.putInt(KEY_TYPE, TYPE_NEWS);
@@ -17349,7 +17421,11 @@
                 NotificationManagerService.WorkerHandler.class);
         mService.setHandler(handler);
         when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
-        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true);
+        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), eq(TYPE_NEWS)))
+                .thenReturn(true);
+        // Blocking adjustments for a different type does nothing
+        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), eq(TYPE_PROMOTION)))
+                .thenReturn(false);
 
         Bundle signals = new Bundle();
         signals.putInt(KEY_TYPE, TYPE_NEWS);
@@ -17364,8 +17440,9 @@
 
         assertThat(r.getChannel().getId()).isEqualTo(NEWS_ID);
 
-        // When we block adjustments for this package
-        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(false);
+        // When we block adjustments for this package/type
+        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), eq(TYPE_PROMOTION)))
+                .thenReturn(false);
 
         signals.putInt(KEY_TYPE, TYPE_PROMOTION);
         mBinderService.applyAdjustmentFromAssistant(null, adjustment);
@@ -17695,7 +17772,7 @@
         when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
         when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true);
         when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
-        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true);
+        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true);
 
         // Post a single notification
         final boolean hasOriginalSummary = false;
@@ -17735,7 +17812,7 @@
         when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
         when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true);
         when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
-        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true);
+        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true);
 
         // Post grouped notifications
         final String originalGroupName = "originalGroup";
@@ -17784,7 +17861,7 @@
         when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
         when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true);
         when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true);
-        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true);
+        when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true);
 
         // Post grouped notifications
         final String originalGroupName = "originalGroup";
diff --git a/services/tests/wmtests/src/com/android/server/policy/PowerKeyGestureTests.java b/services/tests/wmtests/src/com/android/server/policy/PowerKeyGestureTests.java
index 05a1482..33ccec3 100644
--- a/services/tests/wmtests/src/com/android/server/policy/PowerKeyGestureTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/PowerKeyGestureTests.java
@@ -18,11 +18,16 @@
 import static android.view.KeyEvent.KEYCODE_POWER;
 import static android.view.KeyEvent.KEYCODE_VOLUME_UP;
 
+import static com.android.hardware.input.Flags.FLAG_OVERRIDE_POWER_KEY_BEHAVIOR_IN_FOCUSED_WINDOW;
 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_ASSISTANT;
 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_GLOBAL_ACTIONS;
+import static com.android.server.policy.PhoneWindowManager.POWER_MULTI_PRESS_TIMEOUT_MILLIS;
 import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_POWER_DREAM_OR_SLEEP;
 import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_POWER_GO_TO_SLEEP;
 
+import static org.junit.Assert.assertEquals;
+
+import android.platform.test.annotations.EnableFlags;
 import android.provider.Settings;
 import android.view.Display;
 
@@ -39,6 +44,7 @@
     @Before
     public void setUp() {
         setUpPhoneWindowManager();
+        mPhoneWindowManager.overrideStatusBarManagerInternal();
     }
 
     /**
@@ -50,6 +56,8 @@
         sendKey(KEYCODE_POWER);
         mPhoneWindowManager.assertPowerSleep();
 
+        mPhoneWindowManager.moveTimeForward(POWER_MULTI_PRESS_TIMEOUT_MILLIS);
+
         // turn screen on when begin from non-interactive.
         mPhoneWindowManager.overrideDisplayState(Display.STATE_OFF);
         sendKey(KEYCODE_POWER);
@@ -90,7 +98,7 @@
         mPhoneWindowManager.overrideCanStartDreaming(false);
         sendKey(KEYCODE_POWER);
         sendKey(KEYCODE_POWER);
-        mPhoneWindowManager.assertCameraLaunch();
+        mPhoneWindowManager.assertDoublePowerLaunch();
         mPhoneWindowManager.assertDidNotLockAfterAppTransitionFinished();
     }
 
@@ -101,7 +109,7 @@
     public void testPowerDoublePress() {
         sendKey(KEYCODE_POWER);
         sendKey(KEYCODE_POWER);
-        mPhoneWindowManager.assertCameraLaunch();
+        mPhoneWindowManager.assertDoublePowerLaunch();
     }
 
     /**
@@ -111,12 +119,14 @@
     public void testPowerLongPress() {
         // Show assistant.
         mPhoneWindowManager.overrideLongPressOnPower(LONG_PRESS_POWER_ASSISTANT);
-        sendKey(KEYCODE_POWER, true);
+        sendKey(KEYCODE_POWER, SingleKeyGestureDetector.sDefaultLongPressTimeout);
         mPhoneWindowManager.assertSearchManagerLaunchAssist();
 
+        mPhoneWindowManager.moveTimeForward(POWER_MULTI_PRESS_TIMEOUT_MILLIS);
+
         // Show global actions.
         mPhoneWindowManager.overrideLongPressOnPower(LONG_PRESS_POWER_GLOBAL_ACTIONS);
-        sendKey(KEYCODE_POWER, true);
+        sendKey(KEYCODE_POWER, SingleKeyGestureDetector.sDefaultLongPressTimeout);
         mPhoneWindowManager.assertShowGlobalActionsCalled();
     }
 
@@ -141,4 +151,143 @@
         sendKey(KEYCODE_POWER);
         mPhoneWindowManager.assertNoPowerSleep();
     }
+
+
+    /**
+     * Double press of power when the window handles the power key events. The
+     * system double power gesture launch should not be performed.
+     */
+    @Test
+    @EnableFlags(FLAG_OVERRIDE_POWER_KEY_BEHAVIOR_IN_FOCUSED_WINDOW)
+    public void testPowerDoublePress_windowHasOverridePermissionAndKeysHandled() {
+        mPhoneWindowManager.overrideCanWindowOverridePowerKey(true);
+        setDispatchedKeyHandler(keyEvent -> true);
+
+        sendKey(KEYCODE_POWER);
+        sendKey(KEYCODE_POWER);
+
+        mPhoneWindowManager.assertDidNotLockAfterAppTransitionFinished();
+
+        mPhoneWindowManager.assertNoDoublePowerLaunch();
+    }
+
+    /**
+     * Double press of power when the window doesn't handle the power key events.
+     * The system default gesture launch should be performed and the app should receive both events.
+     */
+    @Test
+    @EnableFlags(FLAG_OVERRIDE_POWER_KEY_BEHAVIOR_IN_FOCUSED_WINDOW)
+    public void testPowerDoublePress_windowHasOverridePermissionAndKeysUnHandled() {
+        mPhoneWindowManager.overrideCanWindowOverridePowerKey(true);
+        setDispatchedKeyHandler(keyEvent -> false);
+
+        sendKey(KEYCODE_POWER);
+        sendKey(KEYCODE_POWER);
+
+        mPhoneWindowManager.assertDidNotLockAfterAppTransitionFinished();
+        mPhoneWindowManager.assertDoublePowerLaunch();
+        assertEquals(getDownKeysDispatched(), 2);
+        assertEquals(getUpKeysDispatched(), 2);
+    }
+
+    /**
+     * Triple press of power when the window handles the power key double press gesture.
+     * The system default gesture launch should not be performed, and the app only receives the
+     * first two presses.
+     */
+    @Test
+    @EnableFlags(FLAG_OVERRIDE_POWER_KEY_BEHAVIOR_IN_FOCUSED_WINDOW)
+    public void testPowerTriplePress_windowHasOverridePermissionAndKeysHandled() {
+        mPhoneWindowManager.overrideCanWindowOverridePowerKey(true);
+        setDispatchedKeyHandler(keyEvent -> true);
+
+        sendKey(KEYCODE_POWER);
+        sendKey(KEYCODE_POWER);
+        sendKey(KEYCODE_POWER);
+
+        mPhoneWindowManager.assertDidNotLockAfterAppTransitionFinished();
+        mPhoneWindowManager.assertNoDoublePowerLaunch();
+        assertEquals(getDownKeysDispatched(), 2);
+        assertEquals(getUpKeysDispatched(), 2);
+    }
+
+    /**
+     * Tests a single press, followed by a double press when the window can handle the power key.
+     * The app should receive all 3 events.
+     */
+    @Test
+    @EnableFlags(FLAG_OVERRIDE_POWER_KEY_BEHAVIOR_IN_FOCUSED_WINDOW)
+    public void testPowerTriplePressWithDelay_windowHasOverridePermissionAndKeysHandled() {
+        mPhoneWindowManager.overrideCanWindowOverridePowerKey(true);
+        setDispatchedKeyHandler(keyEvent -> true);
+
+        sendKey(KEYCODE_POWER);
+        mPhoneWindowManager.moveTimeForward(POWER_MULTI_PRESS_TIMEOUT_MILLIS);
+        sendKey(KEYCODE_POWER);
+        sendKey(KEYCODE_POWER);
+
+        mPhoneWindowManager.assertNoDoublePowerLaunch();
+        assertEquals(getDownKeysDispatched(), 3);
+        assertEquals(getUpKeysDispatched(), 3);
+    }
+
+    /**
+     * Tests single press when window doesn't handle the power key. Phone should go to sleep.
+     */
+    @Test
+    @EnableFlags(FLAG_OVERRIDE_POWER_KEY_BEHAVIOR_IN_FOCUSED_WINDOW)
+    public void testPowerSinglePress_windowHasOverridePermissionAndKeyUnhandledByApp() {
+        mPhoneWindowManager.overrideCanWindowOverridePowerKey(true);
+        setDispatchedKeyHandler(keyEvent -> false);
+        mPhoneWindowManager.overrideShortPressOnPower(SHORT_PRESS_POWER_GO_TO_SLEEP);
+
+        sendKey(KEYCODE_POWER);
+
+        mPhoneWindowManager.assertPowerSleep();
+    }
+
+    /**
+     * Tests single press when the window handles the power key. Phone should go to sleep after a
+     * delay of {POWER_MULTI_PRESS_TIMEOUT_MILLIS}
+     */
+    @Test
+    @EnableFlags(FLAG_OVERRIDE_POWER_KEY_BEHAVIOR_IN_FOCUSED_WINDOW)
+    public void testPowerSinglePress_windowHasOverridePermissionAndKeyHandledByApp() {
+        mPhoneWindowManager.overrideCanWindowOverridePowerKey(true);
+        setDispatchedKeyHandler(keyEvent -> true);
+        mPhoneWindowManager.overrideDisplayState(Display.STATE_ON);
+        mPhoneWindowManager.overrideShortPressOnPower(SHORT_PRESS_POWER_GO_TO_SLEEP);
+
+        sendKey(KEYCODE_POWER);
+
+        mPhoneWindowManager.moveTimeForward(POWER_MULTI_PRESS_TIMEOUT_MILLIS);
+
+        mPhoneWindowManager.assertPowerSleep();
+    }
+
+
+    /**
+     * Tests 5x press when the window handles the power key. Emergency gesture should still be
+     * launched.
+     */
+    @Test
+    @EnableFlags(FLAG_OVERRIDE_POWER_KEY_BEHAVIOR_IN_FOCUSED_WINDOW)
+    public void testPowerFiveTimesPress_windowHasOverridePermissionAndKeyHandledByApp() {
+        mPhoneWindowManager.overrideCanWindowOverridePowerKey(true);
+        setDispatchedKeyHandler(keyEvent -> true);
+        mPhoneWindowManager.overrideDisplayState(Display.STATE_ON);
+        mPhoneWindowManager.overrideShortPressOnPower(SHORT_PRESS_POWER_GO_TO_SLEEP);
+
+        int minEmergencyGestureDurationMillis = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_defaultMinEmergencyGestureTapDurationMillis);
+        int durationMillis = minEmergencyGestureDurationMillis / 4;
+        for (int i = 0; i < 5; ++i) {
+            sendKey(KEYCODE_POWER);
+            mPhoneWindowManager.moveTimeForward(durationMillis);
+        }
+
+        mPhoneWindowManager.assertEmergencyLaunch();
+        assertEquals(getDownKeysDispatched(), 2);
+        assertEquals(getUpKeysDispatched(), 2);
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
index 9e47a00..8ede9ef 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java
@@ -85,7 +85,9 @@
     private Resources mResources;
     private PackageManager mPackageManager;
     TestPhoneWindowManager mPhoneWindowManager;
-    DispatchedKeyHandler mDispatchedKeyHandler = event -> false;
+    DispatchedKeyHandler mDispatchedKeyHandler;
+    private int mDownKeysDispatched;
+    private int mUpKeysDispatched;
     Context mContext;
 
     /** Modifier key to meta state */
@@ -116,6 +118,9 @@
         XmlResourceParser testBookmarks = mResources.getXml(
                 com.android.frameworks.wmtests.R.xml.bookmarks);
         doReturn(testBookmarks).when(mResources).getXml(com.android.internal.R.xml.bookmarks);
+        mDispatchedKeyHandler = event -> false;
+        mDownKeysDispatched = 0;
+        mUpKeysDispatched = 0;
 
         try {
             // Keep packageName / className in sync with
@@ -229,6 +234,10 @@
         sendKeyCombination(new int[]{keyCode}, 0 /*durationMillis*/, longPress, DEFAULT_DISPLAY);
     }
 
+    void sendKey(int keyCode, long durationMillis) {
+        sendKeyCombination(new int[]{keyCode}, durationMillis, false, DEFAULT_DISPLAY);
+    }
+
     boolean sendKeyGestureEventStart(int gestureType) {
         return mPhoneWindowManager.sendKeyGestureEvent(
                 new KeyGestureEvent.Builder().setKeyGestureType(gestureType).setAction(
@@ -278,6 +287,14 @@
         doReturn(expectedBehavior).when(mResources).getInteger(eq(resId));
     }
 
+    int getDownKeysDispatched() {
+        return mDownKeysDispatched;
+    }
+
+    int getUpKeysDispatched() {
+        return mUpKeysDispatched;
+    }
+
     private void interceptKey(KeyEvent keyEvent) {
         int actions = mPhoneWindowManager.interceptKeyBeforeQueueing(keyEvent);
         if ((actions & ACTION_PASS_TO_USER) != 0) {
@@ -285,6 +302,11 @@
                 if (!mDispatchedKeyHandler.onKeyDispatched(keyEvent)) {
                     mPhoneWindowManager.interceptUnhandledKey(keyEvent);
                 }
+                if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
+                    ++mDownKeysDispatched;
+                } else {
+                    ++mUpKeysDispatched;
+                }
             }
         }
         mPhoneWindowManager.dispatchAllPendingEvents();
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index 285d94d..6c48ba2 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -37,6 +37,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.hardware.input.Flags.overridePowerKeyBehaviorInFocusedWindow;
 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_ASSISTANT;
 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_GLOBAL_ACTIONS;
 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_GO_TO_VOICE_ASSIST;
@@ -45,10 +46,14 @@
 import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
 import static com.android.server.policy.PhoneWindowManager.POWER_VOLUME_UP_BEHAVIOR_MUTE;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.CALLS_REAL_METHODS;
 import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.atMost;
 import static org.mockito.Mockito.description;
 import static org.mockito.Mockito.mockingDetails;
 import static org.mockito.Mockito.timeout;
@@ -85,7 +90,9 @@
 import android.os.test.TestLooper;
 import android.provider.Settings;
 import android.service.dreams.DreamManagerInternal;
+import android.service.quickaccesswallet.QuickAccessWalletClient;
 import android.telecom.TelecomManager;
+import android.util.MutableBoolean;
 import android.view.Display;
 import android.view.InputEvent;
 import android.view.KeyCharacterMap;
@@ -95,9 +102,12 @@
 
 import com.android.dx.mockito.inline.extended.StaticMockitoSession;
 import com.android.internal.accessibility.AccessibilityShortcutController;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
 import com.android.internal.policy.KeyInterceptionInfo;
 import com.android.server.GestureLauncherService;
 import com.android.server.LocalServices;
+import com.android.server.SystemService;
 import com.android.server.input.InputManagerInternal;
 import com.android.server.inputmethod.InputMethodManagerInternal;
 import com.android.server.pm.UserManagerInternal;
@@ -120,6 +130,7 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.mockito.quality.Strictness;
+import org.mockito.stubbing.Answer;
 
 import java.util.List;
 import java.util.function.Supplier;
@@ -132,6 +143,7 @@
 
     private PhoneWindowManager mPhoneWindowManager;
     private Context mContext;
+    private GestureLauncherService mGestureLauncherService;
 
     @Mock private WindowManagerInternal mWindowManagerInternal;
     @Mock private ActivityManagerInternal mActivityManagerInternal;
@@ -163,7 +175,9 @@
     @Mock private DisplayRotation mDisplayRotation;
     @Mock private DisplayPolicy mDisplayPolicy;
     @Mock private WindowManagerPolicy.ScreenOnListener mScreenOnListener;
-    @Mock private GestureLauncherService mGestureLauncherService;
+    @Mock private QuickAccessWalletClient mQuickAccessWalletClient;
+    @Mock private MetricsLogger mMetricsLogger;
+    @Mock private UiEventLogger mUiEventLogger;
     @Mock private GlobalActions mGlobalActions;
     @Mock private AccessibilityShortcutController mAccessibilityShortcutController;
 
@@ -192,6 +206,8 @@
 
     private int mKeyEventPolicyFlags = FLAG_INTERACTIVE;
 
+    private int mProcessPowerKeyDownCount = 0;
+
     private class TestTalkbackShortcutController extends TalkbackShortcutController {
         TestTalkbackShortcutController(Context context) {
             super(context);
@@ -260,6 +276,8 @@
         MockitoAnnotations.initMocks(this);
         mHandler = new Handler(mTestLooper.getLooper());
         mContext = mockingDetails(context).isSpy() ? context : spy(context);
+        mGestureLauncherService = spy(new GestureLauncherService(mContext, mMetricsLogger,
+                mQuickAccessWalletClient, mUiEventLogger));
         setUp(supportSettingsUpdate);
         mTestLooper.dispatchAll();
     }
@@ -272,6 +290,7 @@
         mMockitoSession = mockitoSession()
                 .mockStatic(LocalServices.class, spyStubOnly)
                 .mockStatic(KeyCharacterMap.class)
+                .mockStatic(GestureLauncherService.class)
                 .strictness(Strictness.LENIENT)
                 .startMocking();
 
@@ -296,6 +315,16 @@
                 () -> LocalServices.getService(eq(DisplayManagerInternal.class)));
         doReturn(mGestureLauncherService).when(
                 () -> LocalServices.getService(eq(GestureLauncherService.class)));
+        doReturn(true).when(
+                () -> GestureLauncherService.isCameraDoubleTapPowerSettingEnabled(any(), anyInt())
+        );
+        doReturn(true).when(
+                () -> GestureLauncherService.isEmergencyGestureSettingEnabled(any(), anyInt())
+        );
+        doReturn(true).when(
+                () -> GestureLauncherService.isGestureLauncherEnabled(any())
+        );
+        mGestureLauncherService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
         doReturn(mUserManagerInternal).when(
                 () -> LocalServices.getService(eq(UserManagerInternal.class)));
         doReturn(null).when(() -> LocalServices.getService(eq(VrManagerInternal.class)));
@@ -375,7 +404,7 @@
         doNothing().when(mContext).startActivityAsUser(any(), any());
         doNothing().when(mContext).startActivityAsUser(any(), any(), any());
 
-        KeyInterceptionInfo interceptionInfo = new KeyInterceptionInfo(0, 0, null, 0);
+        KeyInterceptionInfo interceptionInfo = new KeyInterceptionInfo(0, 0, null, 0, 0);
         doReturn(interceptionInfo)
                 .when(mWindowManagerInternal).getKeyInterceptionInfoFromToken(any());
 
@@ -393,6 +422,8 @@
                 eq(TEST_BROWSER_ROLE_PACKAGE_NAME));
         doReturn(mSmsIntent).when(mPackageManager).getLaunchIntentForPackage(
                 eq(TEST_SMS_ROLE_PACKAGE_NAME));
+        mProcessPowerKeyDownCount = 0;
+        captureProcessPowerKeyDownCount();
 
         Mockito.reset(mContext);
     }
@@ -650,6 +681,12 @@
                 .when(mButtonOverridePermissionChecker).canAppOverrideSystemKey(any(), anyInt());
     }
 
+    void overrideCanWindowOverridePowerKey(boolean granted) {
+        doReturn(granted)
+                .when(mButtonOverridePermissionChecker).canWindowOverridePowerKey(any(), anyInt(),
+                        anyInt());
+    }
+
     void overrideKeyEventPolicyFlags(int flags) {
         mKeyEventPolicyFlags = flags;
     }
@@ -725,11 +762,56 @@
         verify(mPowerManager, never()).goToSleep(anyLong(), anyInt(), anyInt());
     }
 
-    void assertCameraLaunch() {
+    void assertDoublePowerLaunch() {
+        ArgumentCaptor<MutableBoolean> valueCaptor = ArgumentCaptor.forClass(MutableBoolean.class);
+
         mTestLooper.dispatchAll();
-        // GestureLauncherService should receive interceptPowerKeyDown twice.
-        verify(mGestureLauncherService, times(2))
-                .interceptPowerKeyDown(any(), anyBoolean(), any());
+        verify(mGestureLauncherService, atLeast(2))
+                .interceptPowerKeyDown(any(), anyBoolean(), valueCaptor.capture());
+        verify(mGestureLauncherService, atMost(4))
+                .interceptPowerKeyDown(any(), anyBoolean(), valueCaptor.capture());
+
+        if (overridePowerKeyBehaviorInFocusedWindow()) {
+            assertTrue(mProcessPowerKeyDownCount >= 2 && mProcessPowerKeyDownCount <= 4);
+        }
+
+        List<Boolean> capturedValues = valueCaptor.getAllValues().stream()
+                .map(mutableBoolean -> mutableBoolean.value)
+                .toList();
+
+        assertTrue(capturedValues.contains(true));
+    }
+
+    void assertNoDoublePowerLaunch() {
+        ArgumentCaptor<MutableBoolean> valueCaptor = ArgumentCaptor.forClass(MutableBoolean.class);
+
+        mTestLooper.dispatchAll();
+        verify(mGestureLauncherService, atLeast(0))
+                .interceptPowerKeyDown(any(), anyBoolean(), valueCaptor.capture());
+
+        List<Boolean> capturedValues = valueCaptor.getAllValues().stream()
+                .map(mutableBoolean -> mutableBoolean.value)
+                .toList();
+
+        assertTrue(capturedValues.stream().noneMatch(value -> value));
+    }
+
+    void assertEmergencyLaunch() {
+        ArgumentCaptor<MutableBoolean> valueCaptor = ArgumentCaptor.forClass(MutableBoolean.class);
+
+        mTestLooper.dispatchAll();
+        verify(mGestureLauncherService, atLeast(1))
+                .interceptPowerKeyDown(any(), anyBoolean(), valueCaptor.capture());
+
+        if (overridePowerKeyBehaviorInFocusedWindow()) {
+            assertEquals(mProcessPowerKeyDownCount, 5);
+        }
+
+        List<Boolean> capturedValues = valueCaptor.getAllValues().stream()
+                .map(mutableBoolean -> mutableBoolean.value)
+                .toList();
+
+        assertTrue(capturedValues.getLast());
     }
 
     void assertSearchManagerLaunchAssist() {
@@ -952,4 +1034,12 @@
         verify(mContext, never()).startActivityAsUser(any(), any(), any());
         verify(mContext, never()).startActivityAsUser(any(), any());
     }
+
+    private void captureProcessPowerKeyDownCount() {
+        doAnswer((Answer<Void>) invocation -> {
+            invocation.callRealMethod();
+            mProcessPowerKeyDownCount++;
+            return null;
+        }).when(mGestureLauncherService).processPowerKeyDown(any());
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 94a4002..e3e9cc4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -361,12 +361,6 @@
         return prepareStarter(launchFlags, mockGetRootTask, LAUNCH_MULTIPLE);
     }
 
-    private void setupImeWindow() {
-        final WindowState imeWindow = createWindow(null, W_INPUT_METHOD,
-                "mImeWindow", CURRENT_IME_UID);
-        mDisplayContent.mInputMethodWindow = imeWindow;
-    }
-
     /**
      * Creates a {@link ActivityStarter} with default parameters and necessary mocks.
      *
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 57aacd3..5cd2a99 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -85,6 +85,7 @@
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 import static com.android.window.flags.Flags.FLAG_ENABLE_CAMERA_COMPAT_FOR_DESKTOP_WINDOWING;
 import static com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE;
+import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -2879,6 +2880,43 @@
         assertFalse(createNewDisplay().mAppCompatCameraPolicy.hasCameraCompatFreeformPolicy());
     }
 
+    @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
+    @Test
+    public void testSetShouldShowSystemDecorations_defaultDisplay() {
+        DisplayContent dc = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY);
+
+        dc.onDisplayInfoChangeApplied();
+        assertTrue(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
+    }
+
+    @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
+    @Test
+    public void testSetShouldShowSystemDecorations_privateDisplay() {
+        final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
+        displayInfo.flags = FLAG_PRIVATE;
+        final DisplayContent dc = createNewDisplay(displayInfo);
+
+        dc.onDisplayInfoChangeApplied();
+        assertFalse(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
+    }
+
+    @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
+    @Test
+    public void testSetShouldShowSystemDecorations_nonDefaultNonPrivateDisplay() {
+        final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
+        displayInfo.displayId = DEFAULT_DISPLAY + 1;
+        final DisplayContent dc = createNewDisplay(displayInfo);
+
+        spyOn(dc.mDisplay);
+        doReturn(false).when(dc.mDisplay).canHostTasks();
+        dc.onDisplayInfoChangeApplied();
+        assertFalse(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
+
+        doReturn(true).when(dc.mDisplay).canHostTasks();
+        dc.onDisplayInfoChangeApplied();
+        assertTrue(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
+    }
+
     private void removeRootTaskTests(Runnable runnable) {
         final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
         final Task rootTask1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
diff --git a/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java b/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java
index c016c5e..de07168 100644
--- a/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java
@@ -73,7 +73,7 @@
     private static final float MID_REFRESH_RATE = 70;
     private static final float LOW_REFRESH_RATE = 60;
     WindowState createWindow(String name) {
-        WindowState window = createWindow(null, TYPE_APPLICATION, name);
+        WindowState window = newWindowBuilder(name, TYPE_APPLICATION).build();
         when(window.mWmService.mDisplayManagerInternal.getRefreshRateSwitchingType())
                 .thenReturn(DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS);
         return window;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
index f70dceb..7d59f48 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
@@ -56,12 +56,13 @@
 
     @Test
     public void testTransparentControlTargetWindowCanShowIme() {
-        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build();
         makeWindowVisibleAndDrawn(ime);
         mImeProvider.setWindowContainer(ime, null, null);
 
-        final WindowState appWin = createWindow(null, TYPE_APPLICATION, "app");
-        final WindowState popup = createWindow(appWin, TYPE_APPLICATION, "popup");
+        final WindowState appWin = newWindowBuilder("app", TYPE_APPLICATION).build();
+        final WindowState popup = newWindowBuilder("popup", TYPE_APPLICATION).setParent(
+                appWin).build();
         popup.mAttrs.format = PixelFormat.TRANSPARENT;
         mDisplayContent.setImeLayeringTarget(appWin);
         mDisplayContent.updateImeInputAndControlTarget(popup);
@@ -77,11 +78,11 @@
     @Test
     @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
     public void testScheduleShowIme() {
-        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build();
         makeWindowVisibleAndDrawn(ime);
         mImeProvider.setWindowContainer(ime, null, null);
 
-        final WindowState target = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState target = newWindowBuilder("app", TYPE_APPLICATION).build();
         mDisplayContent.setImeLayeringTarget(target);
         mDisplayContent.updateImeInputAndControlTarget(target);
         performSurfacePlacementAndWaitForWindowAnimator();
@@ -105,14 +106,14 @@
     @Test
     @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
     public void testScheduleShowIme_noInitialState() {
-        final WindowState target = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState target = newWindowBuilder("app", TYPE_APPLICATION).build();
 
         // Schedule before anything is ready.
         mImeProvider.scheduleShowImePostLayout(target, ImeTracker.Token.empty());
         assertFalse(mImeProvider.isScheduledAndReadyToShowIme());
         assertFalse(mImeProvider.isImeShowing());
 
-        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build();
         makeWindowVisibleAndDrawn(ime);
         mImeProvider.setWindowContainer(ime, null, null);
 
@@ -133,11 +134,11 @@
     @Test
     @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
     public void testScheduleShowIme_delayedAfterPrepareSurfaces() {
-        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build();
         makeWindowVisibleAndDrawn(ime);
         mImeProvider.setWindowContainer(ime, null, null);
 
-        final WindowState target = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState target = newWindowBuilder("app", TYPE_APPLICATION).build();
         mDisplayContent.setImeLayeringTarget(target);
         mDisplayContent.updateImeInputAndControlTarget(target);
 
@@ -166,11 +167,11 @@
     @Test
     @RequiresFlagsDisabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
     public void testScheduleShowIme_delayedSurfacePlacement() {
-        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build();
         makeWindowVisibleAndDrawn(ime);
         mImeProvider.setWindowContainer(ime, null, null);
 
-        final WindowState target = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState target = newWindowBuilder("app", TYPE_APPLICATION).build();
         mDisplayContent.setImeLayeringTarget(target);
         mDisplayContent.updateImeInputAndControlTarget(target);
 
@@ -191,7 +192,7 @@
 
     @Test
     public void testSetFrozen() {
-        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build();
         makeWindowVisibleAndDrawn(ime);
         mImeProvider.setWindowContainer(ime, null, null);
         mImeProvider.setServerVisible(true);
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index ee56210..6c5fe1d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -106,8 +106,9 @@
         addStatusBar();
         addNavigationBar();
 
-        final WindowState win = createWindow(null, WINDOWING_MODE_FREEFORM,
-                ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app");
+        final WindowState win = newWindowBuilder("app", TYPE_APPLICATION).setActivityType(
+                ACTIVITY_TYPE_STANDARD).setWindowingMode(WINDOWING_MODE_FREEFORM).setDisplay(
+                mDisplayContent).build();
         final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win);
 
         // The app must not control any system bars.
@@ -120,8 +121,9 @@
         addStatusBar();
         addNavigationBar();
 
-        final WindowState win = createWindow(null, WINDOWING_MODE_FREEFORM,
-                ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app");
+        final WindowState win = newWindowBuilder("app", TYPE_APPLICATION).setActivityType(
+                ACTIVITY_TYPE_STANDARD).setWindowingMode(WINDOWING_MODE_FREEFORM).setDisplay(
+                mDisplayContent).build();
         win.setBounds(new Rect());
         final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win);
 
@@ -136,8 +138,9 @@
         addStatusBar();
         addNavigationBar();
 
-        final WindowState win = createWindow(null, WINDOWING_MODE_FREEFORM,
-                ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app");
+        final WindowState win = newWindowBuilder("app", TYPE_APPLICATION).setActivityType(
+                ACTIVITY_TYPE_STANDARD).setWindowingMode(WINDOWING_MODE_FREEFORM).setDisplay(
+                mDisplayContent).build();
         win.getTask().setBounds(new Rect(1, 1, 10, 10));
         final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win);
 
@@ -582,7 +585,7 @@
 
     private WindowState addNavigationBar() {
         final Binder owner = new Binder();
-        final WindowState win = createWindow(null, TYPE_NAVIGATION_BAR, "navBar");
+        final WindowState win = newWindowBuilder("navBar", TYPE_NAVIGATION_BAR).build();
         win.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
         win.mAttrs.providedInsets = new InsetsFrameProvider[] {
                 new InsetsFrameProvider(owner, 0, WindowInsets.Type.navigationBars()),
@@ -595,7 +598,7 @@
 
     private WindowState addStatusBar() {
         final Binder owner = new Binder();
-        final WindowState win = createWindow(null, TYPE_STATUS_BAR, "statusBar");
+        final WindowState win = newWindowBuilder("statusBar", TYPE_STATUS_BAR).build();
         win.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
         win.mAttrs.providedInsets = new InsetsFrameProvider[] {
                 new InsetsFrameProvider(owner, 0, WindowInsets.Type.statusBars()),
@@ -607,7 +610,7 @@
     }
 
     private WindowState addWindow(int type, String name) {
-        final WindowState win = createWindow(null, type, name);
+        final WindowState win = newWindowBuilder(name, type).build();
         mDisplayContent.getDisplayPolicy().addWindowLw(win, win.mAttrs);
         return win;
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index 79967b8..c30aa52 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -63,7 +63,7 @@
 
     @Test
     public void testPostLayout() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
         statusBar.setBounds(0, 0, 500, 1000);
         statusBar.getFrame().set(0, 0, 500, 100);
         statusBar.mHasSurface = true;
@@ -81,7 +81,7 @@
 
     @Test
     public void testPostLayout_invisible() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
         statusBar.setBounds(0, 0, 500, 1000);
         statusBar.getFrame().set(0, 0, 500, 100);
         mProvider.setWindowContainer(statusBar, null, null);
@@ -93,7 +93,7 @@
 
     @Test
     public void testPostLayout_frameProvider() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
         statusBar.getFrame().set(0, 0, 500, 100);
         statusBar.mHasSurface = true;
         mProvider.setWindowContainer(statusBar,
@@ -108,8 +108,8 @@
 
     @Test
     public void testUpdateControlForTarget() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState target = newWindowBuilder("target", TYPE_APPLICATION).build();
         statusBar.getFrame().set(0, 0, 500, 100);
 
         // We must not have control or control target before we have the insets source window.
@@ -153,8 +153,8 @@
 
     @Test
     public void testUpdateControlForFakeTarget() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState target = newWindowBuilder("target", TYPE_APPLICATION).build();
         statusBar.getFrame().set(0, 0, 500, 100);
         mProvider.setWindowContainer(statusBar, null, null);
         mProvider.updateFakeControlTarget(target);
@@ -166,10 +166,10 @@
 
     @Test
     public void testGetLeash() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
-        final WindowState fakeTarget = createWindow(null, TYPE_APPLICATION, "fakeTarget");
-        final WindowState otherTarget = createWindow(null, TYPE_APPLICATION, "otherTarget");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState target = newWindowBuilder("target", TYPE_APPLICATION).build();
+        final WindowState fakeTarget = newWindowBuilder("fakeTarget", TYPE_APPLICATION).build();
+        final WindowState otherTarget = newWindowBuilder("otherTarget", TYPE_APPLICATION).build();
         statusBar.getFrame().set(0, 0, 500, 100);
 
         // We must not have control or control target before we have the insets source window,
@@ -208,7 +208,7 @@
 
     @Test
     public void testUpdateSourceFrame() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
         mProvider.setWindowContainer(statusBar, null, null);
         statusBar.setBounds(0, 0, 500, 1000);
 
@@ -238,7 +238,7 @@
 
     @Test
     public void testUpdateSourceFrameForIme() {
-        final WindowState inputMethod = createWindow(null, TYPE_INPUT_METHOD, "inputMethod");
+        final WindowState inputMethod = newWindowBuilder("inputMethod", TYPE_INPUT_METHOD).build();
 
         inputMethod.getFrame().set(new Rect(0, 400, 500, 500));
 
@@ -262,9 +262,9 @@
 
     @Test
     public void testUpdateInsetsControlPosition() {
-        final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
+        final WindowState target = newWindowBuilder("target", TYPE_APPLICATION).build();
 
-        final WindowState ime1 = createWindow(null, TYPE_INPUT_METHOD, "ime1");
+        final WindowState ime1 = newWindowBuilder("ime1", TYPE_INPUT_METHOD).build();
         ime1.getFrame().set(new Rect(0, 0, 0, 0));
         mImeProvider.setWindowContainer(ime1, null, null);
         mImeProvider.updateControlForTarget(target, false /* force */, null /* statsToken */);
@@ -272,7 +272,7 @@
         mImeProvider.updateInsetsControlPosition(ime1);
         assertEquals(new Point(0, 400), mImeProvider.getControl(target).getSurfacePosition());
 
-        final WindowState ime2 = createWindow(null, TYPE_INPUT_METHOD, "ime2");
+        final WindowState ime2 = newWindowBuilder("ime2", TYPE_INPUT_METHOD).build();
         ime2.getFrame().set(new Rect(0, 0, 0, 0));
         mImeProvider.setWindowContainer(ime2, null, null);
         mImeProvider.updateControlForTarget(target, false /* force */, null /* statsToken */);
@@ -283,8 +283,8 @@
 
     @Test
     public void testSetRequestedVisibleTypes() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState target = newWindowBuilder("target", TYPE_APPLICATION).build();
         statusBar.getFrame().set(0, 0, 500, 100);
         mProvider.setWindowContainer(statusBar, null, null);
         mProvider.updateControlForTarget(target, false /* force */, null /* statsToken */);
@@ -295,8 +295,8 @@
 
     @Test
     public void testSetRequestedVisibleTypes_noControl() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState target = newWindowBuilder("target", TYPE_APPLICATION).build();
         statusBar.getFrame().set(0, 0, 500, 100);
         mProvider.setWindowContainer(statusBar, null, null);
         target.setRequestedVisibleTypes(0, statusBars());
@@ -306,7 +306,7 @@
 
     @Test
     public void testInsetGeometries() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
         statusBar.getFrame().set(0, 0, 500, 100);
         statusBar.mHasSurface = true;
         mProvider.setWindowContainer(statusBar, null, null);
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 66a66a1..973c8d0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -76,9 +76,9 @@
 
     @Test
     public void testStripForDispatch_navBar() {
-        final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");
+        final WindowState navBar = newWindowBuilder("navBar", TYPE_APPLICATION).build();
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState ime = newWindowBuilder("ime", TYPE_APPLICATION).build();
 
         // IME cannot be the IME target.
         ime.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
@@ -96,9 +96,9 @@
 
     @Test
     public void testStripForDispatch_pip() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState navBar = newWindowBuilder("navBar", TYPE_APPLICATION).build();
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
 
         getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
                 .setWindowContainer(statusBar, null, null);
@@ -113,9 +113,9 @@
 
     @Test
     public void testStripForDispatch_freeform() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState navBar = newWindowBuilder("navBar", TYPE_APPLICATION).build();
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
 
         getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
                 .setWindowContainer(statusBar, null, null);
@@ -129,9 +129,9 @@
 
     @Test
     public void testStripForDispatch_multiwindow_alwaysOnTop() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState navBar = newWindowBuilder("navBar", TYPE_APPLICATION).build();
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
 
         getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
                 .setWindowContainer(statusBar, null, null);
@@ -150,8 +150,8 @@
         getController().getOrCreateSourceProvider(ID_IME, ime())
                 .setWindowContainer(mImeWindow, null, null);
 
-        final WindowState app1 = createWindow(null, TYPE_APPLICATION, "app1");
-        final WindowState app2 = createWindow(null, TYPE_APPLICATION, "app2");
+        final WindowState app1 = newWindowBuilder("app1", TYPE_APPLICATION).build();
+        final WindowState app2 = newWindowBuilder("app2", TYPE_APPLICATION).build();
 
         app1.mAboveInsetsState.addSource(getController().getRawInsetsState().peekSource(ID_IME));
 
@@ -166,7 +166,7 @@
         getController().getOrCreateSourceProvider(ID_IME, ime())
                 .setWindowContainer(mImeWindow, null, null);
 
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
         app.mAboveInsetsState.getOrCreateSource(ID_IME, ime())
                 .setVisible(true)
                 .setFrame(mImeWindow.getFrame());
@@ -181,7 +181,7 @@
         getController().getOrCreateSourceProvider(ID_IME, ime())
                 .setWindowContainer(mImeWindow, null, null);
 
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
 
         getController().getRawInsetsState().setSourceVisible(ID_IME, true);
         assertFalse(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
@@ -193,7 +193,7 @@
         // This can be the IME z-order target while app cannot be the IME z-order target.
         // This is also the only IME control target in this test, so IME won't be invisible caused
         // by the control-target change.
-        final WindowState base = createWindow(null, TYPE_APPLICATION, "base");
+        final WindowState base = newWindowBuilder("base", TYPE_APPLICATION).build();
         mDisplayContent.updateImeInputAndControlTarget(base);
 
         // Make IME and stay visible during the test.
@@ -210,7 +210,7 @@
         }
 
         // Send our spy window (app) into the system so that we can detect the invocation.
-        final WindowState win = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState win = newWindowBuilder("app", TYPE_APPLICATION).build();
         win.setHasSurface(true);
         final WindowToken parent = win.mToken;
         parent.removeChild(win);
@@ -250,8 +250,9 @@
         getController().getOrCreateSourceProvider(ID_IME, ime())
                 .setWindowContainer(mImeWindow, null, null);
 
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        final WindowState child = createWindow(app, TYPE_APPLICATION, "child");
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
+        final WindowState child = newWindowBuilder("child", TYPE_APPLICATION).setParent(
+                app).build();
         app.mAboveInsetsState.set(getController().getRawInsetsState());
         child.mAboveInsetsState.set(getController().getRawInsetsState());
         child.mAttrs.flags |= FLAG_ALT_FOCUSABLE_IM;
@@ -271,8 +272,9 @@
         getController().getOrCreateSourceProvider(ID_IME, ime())
                 .setWindowContainer(mImeWindow, null, null);
 
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        final WindowState child = createWindow(app, TYPE_APPLICATION, "child");
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
+        final WindowState child = newWindowBuilder("child", TYPE_APPLICATION).setParent(
+                app).build();
         app.mAboveInsetsState.addSource(getController().getRawInsetsState().peekSource(ID_IME));
         child.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
         child.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
@@ -288,8 +290,8 @@
 
     @Test
     public void testImeForDispatch() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build();
 
         makeWindowVisible(statusBar);
 
@@ -318,11 +320,11 @@
 
     @Test
     public void testBarControllingWinChanged() {
-        final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState climateBar = createWindow(null, TYPE_APPLICATION, "climateBar");
-        final WindowState extraNavBar = createWindow(null, TYPE_APPLICATION, "extraNavBar");
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState navBar = newWindowBuilder("navBar", TYPE_APPLICATION).build();
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState climateBar = newWindowBuilder("climateBar", TYPE_APPLICATION).build();
+        final WindowState extraNavBar = newWindowBuilder("extraNavBar", TYPE_APPLICATION).build();
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
         getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
                 .setWindowContainer(statusBar, null, null);
         getController().getOrCreateSourceProvider(ID_NAVIGATION_BAR, navigationBars())
@@ -338,8 +340,8 @@
 
     @Test
     public void testControlRevoked() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
         getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
                 .setWindowContainer(statusBar, null, null);
         getController().onBarControlTargetChanged(app, null, null, null);
@@ -350,8 +352,8 @@
 
     @Test
     public void testControlRevoked_animation() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
         getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
                 .setWindowContainer(statusBar, null, null);
         getController().onBarControlTargetChanged(app, null, null, null);
@@ -362,19 +364,20 @@
 
     @Test
     public void testControlTargetChangedWhileProviderHasNoWindow() {
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
         final InsetsSourceProvider provider = getController().getOrCreateSourceProvider(
                 ID_STATUS_BAR, statusBars());
         getController().onBarControlTargetChanged(app, null, null, null);
         assertNull(getController().getControlsForDispatch(app));
-        provider.setWindowContainer(createWindow(null, TYPE_APPLICATION, "statusBar"), null, null);
+        provider.setWindowContainer(newWindowBuilder("statusBar", TYPE_APPLICATION).build(), null,
+                null);
         assertNotNull(getController().getControlsForDispatch(app));
     }
 
     @Test
     public void testTransientVisibilityOfFixedRotationState() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
         final InsetsSourceProvider provider = getController()
                 .getOrCreateSourceProvider(ID_STATUS_BAR, statusBars());
         provider.setWindowContainer(statusBar, null, null);
@@ -494,7 +497,8 @@
     @Test
     public void testUpdateAboveInsetsState_imeTargetOnScreenBehavior() {
         final WindowToken imeToken = createTestWindowToken(TYPE_INPUT_METHOD, mDisplayContent);
-        final WindowState ime = createWindow(null,  TYPE_INPUT_METHOD, imeToken, "ime");
+        final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).setWindowToken(
+                imeToken).build();
         final WindowState app = createTestWindow("app");
 
         getController().getOrCreateSourceProvider(ID_IME, ime())
@@ -538,10 +542,10 @@
 
     @Test
     public void testDispatchGlobalInsets() {
-        final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
+        final WindowState navBar = newWindowBuilder("navBar", TYPE_APPLICATION).build();
         getController().getOrCreateSourceProvider(ID_NAVIGATION_BAR, navigationBars())
                 .setWindowContainer(navBar, null, null);
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
         assertNull(app.getInsetsState().peekSource(ID_NAVIGATION_BAR));
         app.mAttrs.receiveInsetsIgnoringZOrder = true;
         assertNotNull(app.getInsetsState().peekSource(ID_NAVIGATION_BAR));
@@ -580,8 +584,8 @@
 
     @Test
     public void testHasPendingControls() {
-        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_APPLICATION).build();
+        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
         getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
                 .setWindowContainer(statusBar, null, null);
         // No controls dispatched yet.
@@ -598,7 +602,7 @@
 
     /** Creates a window which is associated with ActivityRecord. */
     private WindowState createTestWindow(String name) {
-        final WindowState win = createWindow(null, TYPE_APPLICATION, name);
+        final WindowState win = newWindowBuilder(name, TYPE_APPLICATION).build();
         win.setHasSurface(true);
         spyOn(win);
         return win;
@@ -606,7 +610,7 @@
 
     /** Creates a non-activity window. */
     private WindowState createNonAppWindow(String name) {
-        final WindowState win = createWindow(null, LAST_APPLICATION_WINDOW + 1, name);
+        final WindowState win = newWindowBuilder(name, LAST_APPLICATION_WINDOW + 1).build();
         win.setHasSurface(true);
         spyOn(win);
         return win;
diff --git a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
index bef4531..5122aee 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
@@ -239,6 +239,11 @@
         verifyLockTaskStarted(STATUS_BAR_MASK_PINNED, DISABLE2_NONE);
         // THEN screen pinning toast should be shown
         verify(mStatusBarService).showPinningEnterExitToast(eq(true /* entering */));
+
+        // WHEN the app calls startLockTaskMode while the Task is already locked
+        mLockTaskController.startLockTaskMode(tr, false, TEST_UID);
+        // THEN a pinning request should NOT be shown
+        verify(mStatusBarManagerInternal, never()).showScreenPinningRequest(anyInt(), anyInt());
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
index 73e5f58..45436e4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
@@ -108,7 +108,7 @@
     }
 
     WindowState createWindow(String name) {
-        WindowState window = createWindow(null, TYPE_BASE_APPLICATION, name);
+        WindowState window = newWindowBuilder(name, TYPE_BASE_APPLICATION).build();
         when(window.getDisplayInfo()).thenReturn(mDisplayInfo);
         when(window.mWmService.mDisplayManagerInternal.getRefreshRateSwitchingType())
                 .thenReturn(DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index c5cbedb..20381ba2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -114,8 +114,8 @@
     }
 
     private WindowState createAppOverlayWindow() {
-        final WindowState win = createWindow(null /* parent */, TYPE_APPLICATION_OVERLAY,
-                "testOverlayWindow");
+        final WindowState win = newWindowBuilder("testOverlayWindow",
+                TYPE_APPLICATION_OVERLAY).build();
         win.mActivityRecord = null;
         win.mHasSurface = true;
         return win;
@@ -123,7 +123,7 @@
 
     @Test
     public void testForwardsShowBackdrop() throws Exception {
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         mDisplayContent.mOpeningApps.add(win.mActivityRecord);
         final WindowState overlayWin = createAppOverlayWindow();
         try {
@@ -156,7 +156,7 @@
 
     @Test
     public void testRun() throws Exception {
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         mDisplayContent.mOpeningApps.add(win.mActivityRecord);
         final WindowState overlayWin = createAppOverlayWindow();
         try {
@@ -200,7 +200,7 @@
 
     @Test
     public void testCancel() throws Exception {
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
                 win.mActivityRecord,
                 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter;
@@ -214,7 +214,7 @@
 
     @Test
     public void testTimeout() throws Exception {
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
                 win.mActivityRecord,
                 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter;
@@ -234,8 +234,7 @@
     public void testTimeout_scaled() throws Exception {
         try {
             mWm.setAnimationScale(2, 5.0f);
-            final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION,
-                    "testWin");
+            final WindowState win = createTestWindow();
             final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
                     win.mActivityRecord, new Point(50, 100), null, new Rect(50, 100, 150, 150),
                     null, false).mAdapter;
@@ -268,7 +267,7 @@
 
     @Test
     public void testNotReallyStarted() throws Exception {
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         mController.createRemoteAnimationRecord(win.mActivityRecord,
                 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false);
         mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
@@ -278,8 +277,8 @@
 
     @Test
     public void testOneNotStarted() throws Exception {
-        final WindowState win1 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin1");
-        final WindowState win2 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin2");
+        final WindowState win1 = newWindowBuilder("testWin1", TYPE_BASE_APPLICATION).build();
+        final WindowState win2 = newWindowBuilder("testWin2", TYPE_BASE_APPLICATION).build();
         mController.createRemoteAnimationRecord(win1.mActivityRecord,
                 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false);
         final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
@@ -306,7 +305,7 @@
 
     @Test
     public void testRemovedBeforeStarted() throws Exception {
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
                 win.mActivityRecord,
                 new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter;
@@ -322,7 +321,7 @@
 
     @Test
     public void testOpeningTaskWithTopFinishingActivity() {
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "win");
+        final WindowState win = createTestWindow();
         final Task task = win.getTask();
         final ActivityRecord topFinishing = new ActivityBuilder(mAtm).setTask(task).build();
         // Now the task contains:
@@ -348,7 +347,7 @@
 
     @Test
     public void testChangeToSmallerSize() throws Exception {
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         mDisplayContent.mChangingContainers.add(win.mActivityRecord);
         try {
             final RemoteAnimationRecord record = mController.createRemoteAnimationRecord(
@@ -402,7 +401,7 @@
 
     @Test
     public void testChangeTolargerSize() throws Exception {
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         mDisplayContent.mChangingContainers.add(win.mActivityRecord);
         try {
             final RemoteAnimationRecord record = mController.createRemoteAnimationRecord(
@@ -456,7 +455,7 @@
 
     @Test
     public void testChangeToDifferentPosition() throws Exception {
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         mDisplayContent.mChangingContainers.add(win.mActivityRecord);
         try {
             final RemoteAnimationRecord record = mController.createRemoteAnimationRecord(
@@ -515,7 +514,7 @@
                 true, mDisplayContent, true /* ownerCanManageAppTokens */);
         spyOn(mDisplayContent.mWallpaperController);
         doReturn(true).when(mDisplayContent.mWallpaperController).isWallpaperVisible();
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         mDisplayContent.mOpeningApps.add(win.mActivityRecord);
         try {
             final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
@@ -548,7 +547,7 @@
                 true, mDisplayContent, true /* ownerCanManageAppTokens */);
         spyOn(mDisplayContent.mWallpaperController);
         doReturn(true).when(mDisplayContent.mWallpaperController).isWallpaperVisible();
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         mDisplayContent.mOpeningApps.add(win.mActivityRecord);
         try {
             final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
@@ -581,7 +580,7 @@
 
     @Test
     public void testNonAppIncluded_keygaurdGoingAway() throws Exception {
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         mDisplayContent.mOpeningApps.add(win.mActivityRecord);
         // Add overlay window hidden by the keyguard.
         final WindowState overlayWin = createAppOverlayWindow();
@@ -631,7 +630,7 @@
                 true, mDisplayContent, true /* ownerCanManageAppTokens */);
         spyOn(mDisplayContent.mWallpaperController);
         doReturn(true).when(mDisplayContent.mWallpaperController).isWallpaperVisible();
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         mDisplayContent.mOpeningApps.add(win.mActivityRecord);
         // Add overlay window hidden by the keyguard.
         final WindowState overlayWin = createAppOverlayWindow();
@@ -729,9 +728,9 @@
     }
 
     private AnimationAdapter setupForNonAppTargetNavBar(int transit, boolean shouldAttachNavBar) {
-        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        final WindowState win = createTestWindow();
         mDisplayContent.mOpeningApps.add(win.mActivityRecord);
-        final WindowState navBar = createWindow(null, TYPE_NAVIGATION_BAR, "NavigationBar");
+        final WindowState navBar = newWindowBuilder("NavigationBar", TYPE_NAVIGATION_BAR).build();
         mDisplayContent.getDisplayPolicy().addWindowLw(navBar, navBar.mAttrs);
         final DisplayPolicy policy = mDisplayContent.getDisplayPolicy();
         spyOn(policy);
@@ -751,4 +750,8 @@
         verify(binder, atLeast(0)).asBinder();
         verifyNoMoreInteractions(binder);
     }
+
+    private WindowState createTestWindow() {
+        return newWindowBuilder("testWin", TYPE_BASE_APPLICATION).build();
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 6a738ae5..9d9f24c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -673,7 +673,8 @@
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
 
         prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
-        final WindowState window = createWindow(null, TYPE_BASE_APPLICATION, mActivity, "window");
+        final WindowState window = newWindowBuilder("window", TYPE_BASE_APPLICATION).setWindowToken(
+                mActivity).build();
 
         assertEquals(window, mActivity.findMainWindow());
 
@@ -3996,8 +3997,8 @@
         resizeDisplay(display, 2200, 2280);
         display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         // Simulate insets, final app bounds are (0, 0, 2200, 2130) - landscape.
-        final WindowState navbar = createWindow(null, TYPE_NAVIGATION_BAR, mDisplayContent,
-                "navbar");
+        final WindowState navbar = newWindowBuilder("navbar", TYPE_NAVIGATION_BAR).setDisplay(
+                mDisplayContent).build();
         final Binder owner = new Binder();
         navbar.mAttrs.providedInsets = new InsetsFrameProvider[] {
                 new InsetsFrameProvider(owner, 0, WindowInsets.Type.navigationBars())
@@ -4030,8 +4031,8 @@
         resizeDisplay(display, 2200, 2280);
         display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         // Simulate taskbar, final app bounds are (0, 0, 2200, 2130) - landscape
-        final WindowState navbar = createWindow(null, TYPE_NAVIGATION_BAR, mDisplayContent,
-                "navbar");
+        final WindowState navbar = newWindowBuilder("navbar", TYPE_NAVIGATION_BAR).setDisplay(
+                mDisplayContent).build();
         final Binder owner = new Binder();
         navbar.mAttrs.providedInsets = new InsetsFrameProvider[] {
                 new InsetsFrameProvider(owner, 0, WindowInsets.Type.navigationBars())
@@ -4059,8 +4060,8 @@
         resizeDisplay(dc, 2200, 2280);
         dc.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         // Simulate taskbar, final app bounds are (0, 0, 2200, 2130) - landscape
-        final WindowState navbar = createWindow(null, TYPE_NAVIGATION_BAR, mDisplayContent,
-                "navbar");
+        final WindowState navbar = newWindowBuilder("navbar", TYPE_NAVIGATION_BAR).setDisplay(
+                mDisplayContent).build();
         final Binder owner = new Binder();
         navbar.mAttrs.providedInsets = new InsetsFrameProvider[] {
                 new InsetsFrameProvider(owner, 0, WindowInsets.Type.navigationBars())
diff --git a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
index 1c32980..da5210c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
@@ -152,9 +152,9 @@
         final Task task = taskRoot.getTask();
         final ActivityRecord translucentTop = new ActivityBuilder(mAtm).setTask(task)
                 .setActivityTheme(android.R.style.Theme_Translucent).build();
-        createWindow(null, TYPE_BASE_APPLICATION, taskRoot, "win");
-        final WindowState startingWindow = createWindow(null, TYPE_APPLICATION_STARTING,
-                translucentTop, "starting");
+        newWindowBuilder("win", TYPE_BASE_APPLICATION).setWindowToken(taskRoot).build();
+        final WindowState startingWindow = newWindowBuilder("starting",
+                TYPE_APPLICATION_STARTING).setWindowToken(translucentTop).build();
         startingWindow.mStartingData = new SnapshotStartingData(mWm, null, 0);
         task.mSharedStartingData = startingWindow.mStartingData;
         task.prepareSync();
@@ -355,7 +355,7 @@
         assertEquals(SYNC_STATE_NONE, botChildWC.mSyncState);
 
         // If the appearance of window won't change after reparenting, its sync state can be kept.
-        final WindowState w = createWindow(null, TYPE_BASE_APPLICATION, "win");
+        final WindowState w = newWindowBuilder("win", TYPE_BASE_APPLICATION).build();
         parentWC.onRequestedOverrideConfigurationChanged(w.getConfiguration());
         w.reparent(botChildWC, POSITION_TOP);
         parentWC.prepareSync();
@@ -435,7 +435,7 @@
 
     @Test
     public void testNonBlastMethod() {
-        mAppWindow = createWindow(null, TYPE_BASE_APPLICATION, "mAppWindow");
+        mAppWindow = newWindowBuilder("mAppWindow", TYPE_BASE_APPLICATION).build();
 
         final BLASTSyncEngine bse = createTestBLASTSyncEngine();
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 35a2546..c0f251e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -52,6 +52,7 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.clearInvocations;
@@ -1070,94 +1071,106 @@
 
     @EnableFlags(Flags.FLAG_ALLOW_MULTIPLE_ADJACENT_TASK_FRAGMENTS)
     @Test
-    public void testSetAdjacentTaskFragments() {
+    public void testAdjacentSetForTaskFragments() {
         final Task task = createTask(mDisplayContent);
         final TaskFragment tf0 = createTaskFragmentWithActivity(task);
         final TaskFragment tf1 = createTaskFragmentWithActivity(task);
         final TaskFragment tf2 = createTaskFragmentWithActivity(task);
-        final TaskFragment.AdjacentSet adjacentTfs = new TaskFragment.AdjacentSet(tf0, tf1, tf2);
-        assertFalse(tf0.hasAdjacentTaskFragment());
 
-        tf0.setAdjacentTaskFragments(adjacentTfs);
+        // Can have two TFs adjacent,
+        new TaskFragment.AdjacentSet(tf0, tf1);
 
-        assertSame(adjacentTfs, tf0.getAdjacentTaskFragments());
-        assertSame(adjacentTfs, tf1.getAdjacentTaskFragments());
-        assertSame(adjacentTfs, tf2.getAdjacentTaskFragments());
-        assertTrue(tf0.hasAdjacentTaskFragment());
-        assertTrue(tf1.hasAdjacentTaskFragment());
-        assertTrue(tf2.hasAdjacentTaskFragment());
+        // 3+ TFs adjacent is not yet supported.
+        assertThrows(IllegalArgumentException.class,
+                () -> new TaskFragment.AdjacentSet(tf0, tf1, tf2));
+    }
 
-        final TaskFragment.AdjacentSet adjacentTfs2 = new TaskFragment.AdjacentSet(tf0, tf1);
-        tf0.setAdjacentTaskFragments(adjacentTfs2);
+    @EnableFlags(Flags.FLAG_ALLOW_MULTIPLE_ADJACENT_TASK_FRAGMENTS)
+    @Test
+    public void testSetAdjacentTaskFragments() {
+        final Task task0 = createTask(mDisplayContent);
+        final Task task1 = createTask(mDisplayContent);
+        final Task task2 = createTask(mDisplayContent);
+        final TaskFragment.AdjacentSet adjTasks = new TaskFragment.AdjacentSet(task0, task1, task2);
+        assertFalse(task0.hasAdjacentTaskFragment());
 
-        assertSame(adjacentTfs2, tf0.getAdjacentTaskFragments());
-        assertSame(adjacentTfs2, tf1.getAdjacentTaskFragments());
-        assertNull(tf2.getAdjacentTaskFragments());
-        assertTrue(tf0.hasAdjacentTaskFragment());
-        assertTrue(tf1.hasAdjacentTaskFragment());
-        assertFalse(tf2.hasAdjacentTaskFragment());
+        task0.setAdjacentTaskFragments(adjTasks);
+
+        assertSame(adjTasks, task0.getAdjacentTaskFragments());
+        assertSame(adjTasks, task1.getAdjacentTaskFragments());
+        assertSame(adjTasks, task2.getAdjacentTaskFragments());
+        assertTrue(task0.hasAdjacentTaskFragment());
+        assertTrue(task1.hasAdjacentTaskFragment());
+        assertTrue(task2.hasAdjacentTaskFragment());
+
+        final TaskFragment.AdjacentSet adjTasks2 = new TaskFragment.AdjacentSet(task0, task1);
+        task0.setAdjacentTaskFragments(adjTasks2);
+
+        assertSame(adjTasks2, task0.getAdjacentTaskFragments());
+        assertSame(adjTasks2, task1.getAdjacentTaskFragments());
+        assertNull(task2.getAdjacentTaskFragments());
+        assertTrue(task0.hasAdjacentTaskFragment());
+        assertTrue(task1.hasAdjacentTaskFragment());
+        assertFalse(task2.hasAdjacentTaskFragment());
     }
 
     @EnableFlags(Flags.FLAG_ALLOW_MULTIPLE_ADJACENT_TASK_FRAGMENTS)
     @Test
     public void testClearAdjacentTaskFragments() {
-        final Task task = createTask(mDisplayContent);
-        final TaskFragment tf0 = createTaskFragmentWithActivity(task);
-        final TaskFragment tf1 = createTaskFragmentWithActivity(task);
-        final TaskFragment tf2 = createTaskFragmentWithActivity(task);
-        final TaskFragment.AdjacentSet adjacentTfs = new TaskFragment.AdjacentSet(tf0, tf1, tf2);
-        tf0.setAdjacentTaskFragments(adjacentTfs);
+        final Task task0 = createTask(mDisplayContent);
+        final Task task1 = createTask(mDisplayContent);
+        final Task task2 = createTask(mDisplayContent);
+        final TaskFragment.AdjacentSet adjTasks = new TaskFragment.AdjacentSet(task0, task1, task2);
+        task0.setAdjacentTaskFragments(adjTasks);
 
-        tf0.clearAdjacentTaskFragments();
+        task0.clearAdjacentTaskFragments();
 
-        assertNull(tf0.getAdjacentTaskFragments());
-        assertNull(tf1.getAdjacentTaskFragments());
-        assertNull(tf2.getAdjacentTaskFragments());
-        assertFalse(tf0.hasAdjacentTaskFragment());
-        assertFalse(tf1.hasAdjacentTaskFragment());
-        assertFalse(tf2.hasAdjacentTaskFragment());
+        assertNull(task0.getAdjacentTaskFragments());
+        assertNull(task1.getAdjacentTaskFragments());
+        assertNull(task2.getAdjacentTaskFragments());
+        assertFalse(task0.hasAdjacentTaskFragment());
+        assertFalse(task1.hasAdjacentTaskFragment());
+        assertFalse(task2.hasAdjacentTaskFragment());
     }
 
     @EnableFlags(Flags.FLAG_ALLOW_MULTIPLE_ADJACENT_TASK_FRAGMENTS)
     @Test
     public void testRemoveFromAdjacentTaskFragments() {
-        final Task task = createTask(mDisplayContent);
-        final TaskFragment tf0 = createTaskFragmentWithActivity(task);
-        final TaskFragment tf1 = createTaskFragmentWithActivity(task);
-        final TaskFragment tf2 = createTaskFragmentWithActivity(task);
-        final TaskFragment.AdjacentSet adjacentTfs = new TaskFragment.AdjacentSet(tf0, tf1, tf2);
-        tf0.setAdjacentTaskFragments(adjacentTfs);
+        final Task task0 = createTask(mDisplayContent);
+        final Task task1 = createTask(mDisplayContent);
+        final Task task2 = createTask(mDisplayContent);
+        final TaskFragment.AdjacentSet adjTasks = new TaskFragment.AdjacentSet(task0, task1, task2);
+        task0.setAdjacentTaskFragments(adjTasks);
 
-        tf0.removeFromAdjacentTaskFragments();
+        task0.removeFromAdjacentTaskFragments();
 
-        assertNull(tf0.getAdjacentTaskFragments());
-        assertSame(adjacentTfs, tf1.getAdjacentTaskFragments());
-        assertSame(adjacentTfs, tf2.getAdjacentTaskFragments());
-        assertFalse(adjacentTfs.contains(tf0));
-        assertTrue(tf1.isAdjacentTo(tf2));
-        assertTrue(tf2.isAdjacentTo(tf1));
-        assertFalse(tf1.isAdjacentTo(tf0));
-        assertFalse(tf0.isAdjacentTo(tf1));
-        assertFalse(tf0.isAdjacentTo(tf0));
-        assertFalse(tf1.isAdjacentTo(tf1));
+        assertNull(task0.getAdjacentTaskFragments());
+        assertSame(adjTasks, task1.getAdjacentTaskFragments());
+        assertSame(adjTasks, task2.getAdjacentTaskFragments());
+        assertFalse(adjTasks.contains(task0));
+        assertTrue(task1.isAdjacentTo(task2));
+        assertTrue(task2.isAdjacentTo(task1));
+        assertFalse(task1.isAdjacentTo(task0));
+        assertFalse(task0.isAdjacentTo(task1));
+        assertFalse(task0.isAdjacentTo(task0));
+        assertFalse(task1.isAdjacentTo(task1));
     }
 
     @EnableFlags(Flags.FLAG_ALLOW_MULTIPLE_ADJACENT_TASK_FRAGMENTS)
     @Test
     public void testRemoveFromAdjacentTaskFragmentsWhenRemove() {
-        final Task task = createTask(mDisplayContent);
-        final TaskFragment tf0 = createTaskFragmentWithActivity(task);
-        final TaskFragment tf1 = createTaskFragmentWithActivity(task);
-        final TaskFragment tf2 = createTaskFragmentWithActivity(task);
-        final TaskFragment.AdjacentSet adjacentTfs = new TaskFragment.AdjacentSet(tf0, tf1, tf2);
-        tf0.setAdjacentTaskFragments(adjacentTfs);
+        final Task task0 = createTask(mDisplayContent);
+        final Task task1 = createTask(mDisplayContent);
+        final Task task2 = createTask(mDisplayContent);
+        final TaskFragment.AdjacentSet adjTasks = new TaskFragment.AdjacentSet(task0, task1, task2);
+        task0.setAdjacentTaskFragments(adjTasks);
 
-        tf0.removeImmediately();
+        task0.removeImmediately();
 
-        assertNull(tf0.getAdjacentTaskFragments());
-        assertSame(adjacentTfs, tf1.getAdjacentTaskFragments());
-        assertSame(adjacentTfs, tf2.getAdjacentTaskFragments());
-        assertFalse(adjacentTfs.contains(tf0));
+        assertNull(task0.getAdjacentTaskFragments());
+        assertSame(adjTasks, task1.getAdjacentTaskFragments());
+        assertSame(adjTasks, task2.getAdjacentTaskFragments());
+        assertFalse(adjTasks.contains(task0));
     }
 
     private WindowState createAppWindow(ActivityRecord app, String name) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index 78f32c1..2ee34d3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -433,8 +433,8 @@
 
         final WallpaperWindowToken wallpaperWindowToken = spy(new WallpaperWindowToken(mWm,
                 mock(IBinder.class), true, mDisplayContent, true /* ownerCanManageAppTokens */));
-        final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, wallpaperWindowToken,
-                "wallpaperWindow");
+        final WindowState wallpaperWindow = newWindowBuilder("wallpaperWindow",
+                TYPE_WALLPAPER).setWindowToken(wallpaperWindowToken).build();
         wallpaperWindowToken.setVisibleRequested(false);
         transition.collect(wallpaperWindowToken);
         wallpaperWindowToken.setVisibleRequested(true);
@@ -630,8 +630,8 @@
         // Make DA organized so we can check that they don't get included.
         WindowContainer parent = wallpaperWindowToken.getParent();
         makeDisplayAreaOrganized(parent, mDisplayContent);
-        final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, wallpaperWindowToken,
-                "wallpaperWindow");
+        final WindowState wallpaperWindow = newWindowBuilder("wallpaperWindow",
+                TYPE_WALLPAPER).setWindowToken(wallpaperWindowToken).build();
         wallpaperWindowToken.setVisibleRequested(false);
         transition.collect(wallpaperWindowToken);
         wallpaperWindowToken.setVisibleRequested(true);
@@ -1114,15 +1114,15 @@
         // Simulate gesture navigation (non-movable) so it is not seamless.
         doReturn(false).when(displayPolicy).navigationBarCanMove();
         final Task task = createActivityRecord(mDisplayContent).getTask();
-        final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar");
-        final WindowState navBar = createWindow(null, TYPE_NAVIGATION_BAR, "navBar");
-        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_STATUS_BAR).build();
+        final WindowState navBar = newWindowBuilder("navBar", TYPE_NAVIGATION_BAR).build();
+        final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build();
         final WindowToken decorToken = new WindowToken.Builder(mWm, mock(IBinder.class),
                 TYPE_NAVIGATION_BAR_PANEL).setDisplayContent(mDisplayContent)
                 .setRoundedCornerOverlay(true).build();
-        final WindowState screenDecor =
-                createWindow(null, decorToken.windowType, decorToken, "screenDecor");
-        final WindowState[] windows = { statusBar, navBar, ime, screenDecor };
+        final WindowState screenDecor = newWindowBuilder("screenDecor",
+                decorToken.windowType).setWindowToken(decorToken).build();
+        final WindowState[] windows = {statusBar, navBar, ime, screenDecor};
         makeWindowVisible(windows);
         mDisplayContent.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs);
         mDisplayContent.getDisplayPolicy().addWindowLw(navBar, navBar.mAttrs);
@@ -1191,7 +1191,7 @@
     }
 
     private void testShellRotationOpen(TestTransitionPlayer player) {
-        final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_STATUS_BAR).build();
         makeWindowVisible(statusBar);
         mDisplayContent.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs);
         final ActivityRecord app = createActivityRecord(mDisplayContent);
@@ -1239,7 +1239,7 @@
     }
 
     private void testFixedRotationOpen(TestTransitionPlayer player) {
-        final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar");
+        final WindowState statusBar = newWindowBuilder("statusBar", TYPE_STATUS_BAR).build();
         makeWindowVisible(statusBar);
         mDisplayContent.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs);
         final WindowState navBar = createNavBarWithProvidedInsets(mDisplayContent);
@@ -2272,15 +2272,24 @@
             public void cleanUp(SurfaceControl.Transaction t) {
             }
         });
+        assertEquals(WindowAnimator.PENDING_STATE_NONE, mWm.mAnimator.mPendingState);
+        app.startAnimation(app.getPendingTransaction(), mock(AnimationAdapter.class),
+                false /* hidden */, SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION);
+        assertEquals(WindowAnimator.PENDING_STATE_HAS_CHANGES, mWm.mAnimator.mPendingState);
+
         final Task task = app.getTask();
         transition.collect(task);
+        assertEquals(WindowAnimator.PENDING_STATE_NEED_APPLY, mWm.mAnimator.mPendingState);
         final Rect bounds = new Rect(task.getBounds());
         Configuration c = new Configuration(task.getRequestedOverrideConfiguration());
         bounds.inset(10, 10);
         c.windowConfiguration.setBounds(bounds);
         task.onRequestedOverrideConfigurationChanged(c);
         assertTrue(freezeCalls.contains(task));
-        transition.abort();
+
+        transition.start();
+        mWm.mSyncEngine.abort(transition.getSyncId());
+        assertEquals(WindowAnimator.PENDING_STATE_NONE, mWm.mAnimator.mPendingState);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index eb89a9f..358448e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -243,8 +243,8 @@
 
         final WindowState homeWindow = createWallpaperTargetWindow(dc);
 
-        WindowState otherWindow = createWindow(null /* parent */, TYPE_APPLICATION, dc,
-                "otherWindow");
+        WindowState otherWindow = newWindowBuilder("otherWindow", TYPE_APPLICATION).setDisplay(
+                dc).build();
 
         dc.mWallpaperController.adjustWallpaperWindows();
 
@@ -275,7 +275,7 @@
     public void testUpdateWallpaperTarget() {
         final DisplayContent dc = mDisplayContent;
         final WindowState homeWin = createWallpaperTargetWindow(dc);
-        final WindowState appWin = createWindow(null, TYPE_BASE_APPLICATION, "app");
+        final WindowState appWin = newWindowBuilder("app", TYPE_BASE_APPLICATION).build();
         appWin.mAttrs.flags |= FLAG_SHOW_WALLPAPER;
         makeWindowVisible(appWin);
 
@@ -290,9 +290,9 @@
     public void testShowWhenLockedWallpaperTarget() {
         final WindowState wallpaperWindow = createWallpaperWindow(mDisplayContent);
         wallpaperWindow.mToken.asWallpaperToken().setShowWhenLocked(true);
-        final WindowState behind = createWindow(null, TYPE_BASE_APPLICATION, "behind");
-        final WindowState topTranslucent = createWindow(null, TYPE_BASE_APPLICATION,
-                "topTranslucent");
+        final WindowState behind = newWindowBuilder("behind", TYPE_BASE_APPLICATION).build();
+        final WindowState topTranslucent = newWindowBuilder("topTranslucent",
+                TYPE_BASE_APPLICATION).build();
         behind.mAttrs.width = behind.mAttrs.height = topTranslucent.mAttrs.width =
                 topTranslucent.mAttrs.height = WindowManager.LayoutParams.MATCH_PARENT;
         topTranslucent.mAttrs.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
@@ -314,8 +314,8 @@
 
         // Only transient-launch transition will make notification shade as last resort target.
         // This verifies that regular transition won't choose invisible keyguard as the target.
-        final WindowState keyguard = createWindow(null /* parent */,
-                WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE, "keyguard");
+        final WindowState keyguard = newWindowBuilder("keyguard",
+                WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE).build();
         keyguard.mAttrs.flags |= FLAG_SHOW_WALLPAPER;
         registerTestTransitionPlayer();
         final Transition transition = wallpaperWindow.mTransitionController.createTransition(
@@ -568,8 +568,8 @@
     private WindowState createWallpaperWindow(DisplayContent dc) {
         final WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class),
                 true /* explicit */, dc, true /* ownerCanManageAppTokens */);
-        return createWindow(null /* parent */, TYPE_WALLPAPER, wallpaperWindowToken,
-                "wallpaperWindow");
+        return newWindowBuilder("wallpaperWindow", TYPE_WALLPAPER).setWindowToken(
+                wallpaperWindowToken).build();
     }
 
     private WindowState createWallpaperTargetWindow(DisplayContent dc) {
@@ -578,8 +578,8 @@
                 .build();
         homeActivity.setVisibility(true);
 
-        WindowState appWindow = createWindow(null /* parent */, TYPE_BASE_APPLICATION,
-                homeActivity, "wallpaperTargetWindow");
+        WindowState appWindow = newWindowBuilder("wallpaperTargetWindow",
+                TYPE_BASE_APPLICATION).setWindowToken(homeActivity).build();
         appWindow.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
         appWindow.mHasSurface = true;
         spyOn(appWindow);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index e7c9e92..e27dbe5 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -1869,10 +1869,18 @@
     }
 
     private boolean shouldDeleteObsoleteData(UserHandle userHandle) {
-        final DevicePolicyManagerInternal dpmInternal = getDpmInternal();
-        // If a profile owner is not defined for the given user, obsolete data should be deleted
-        return dpmInternal == null
-                || dpmInternal.getProfileOwnerOrDeviceOwnerSupervisionComponent(userHandle) == null;
+        if (android.app.supervision.flags.Flags.deprecateDpmSupervisionApis()) {
+            final SupervisionManagerInternal smInternal = getSupervisionManagerInternal();
+            // If supervision is not enabled for the given user, obsolete data should be deleted.
+            return smInternal == null
+                    || !smInternal.isSupervisionEnabledForUser(userHandle.getIdentifier());
+        } else {
+            final DevicePolicyManagerInternal dpmInternal = getDpmInternal();
+            // If a profile owner is not defined for the given user, obsolete data should be deleted
+            return dpmInternal == null
+                    || dpmInternal.getProfileOwnerOrDeviceOwnerSupervisionComponent(userHandle)
+                            == null;
+        }
     }
 
     private String buildFullToken(String packageName, String token) {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index fa4ec16..d3f98d1 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -10596,6 +10596,8 @@
      *     <!-- Handover from 4G to IWLAN is not allowed if the device has capability in either IMS
      *     or EIMS-->
      *     <item value="source=EUTRAN, target=IWLAN, type=disallowed, capabilities=IMS|EIMS"/>
+     *     <!-- Handover from IWLAN to 5G is not allowed if the device is incall. -->
+     *     <item value="source=IWLAN, target=NGRAN, incall=true, type=disallowed"/>
      *     <!-- Handover is always allowed in any condition. -->
      *     <item value="source=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN|UNKNOWN,
      *         target=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN, type=allowed"/>
diff --git a/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt b/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt
index aea75d8..d75a8f4 100644
--- a/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt
+++ b/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt
@@ -613,7 +613,8 @@
                 0
             },
             "title",
-            /* uid = */0
+            /* uid = */0,
+            /* inputFeatureFlags = */ 0
         )
         whenever(windowManagerInternal.getKeyInterceptionInfoFromToken(any())).thenReturn(info)
     }
diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
index 4959cb3..4d7085f 100644
--- a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
@@ -466,27 +466,27 @@
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
             ),
             TestData(
-                "META + ALT + DPAD_LEFT -> Change Splitscreen Focus Left",
+                "CTRL + ALT + DPAD_LEFT -> Change Splitscreen Focus Left",
                 intArrayOf(
-                    KeyEvent.KEYCODE_META_LEFT,
+                    KeyEvent.KEYCODE_CTRL_LEFT,
                     KeyEvent.KEYCODE_ALT_LEFT,
                     KeyEvent.KEYCODE_DPAD_LEFT
                 ),
                 KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_LEFT,
                 intArrayOf(KeyEvent.KEYCODE_DPAD_LEFT),
-                KeyEvent.META_META_ON or KeyEvent.META_ALT_ON,
+                KeyEvent.META_CTRL_ON or KeyEvent.META_ALT_ON,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
             ),
             TestData(
-                "META + CTRL + DPAD_RIGHT -> Change Splitscreen Focus Right",
+                "CTRL + ALT + DPAD_RIGHT -> Change Splitscreen Focus Right",
                 intArrayOf(
-                    KeyEvent.KEYCODE_META_LEFT,
+                    KeyEvent.KEYCODE_CTRL_LEFT,
                     KeyEvent.KEYCODE_ALT_LEFT,
                     KeyEvent.KEYCODE_DPAD_RIGHT
                 ),
                 KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS_RIGHT,
                 intArrayOf(KeyEvent.KEYCODE_DPAD_RIGHT),
-                KeyEvent.META_META_ON or KeyEvent.META_ALT_ON,
+                KeyEvent.META_CTRL_ON or KeyEvent.META_ALT_ON,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
             ),
             TestData(
@@ -735,25 +735,25 @@
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
             ),
             TestData(
-                "META + ALT + '-' -> Magnifier Zoom Out",
+                "META + ALT + '-' -> Magnification Zoom Out",
                 intArrayOf(
                     KeyEvent.KEYCODE_META_LEFT,
                     KeyEvent.KEYCODE_ALT_LEFT,
                     KeyEvent.KEYCODE_MINUS
                 ),
-                KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_OUT,
+                KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT,
                 intArrayOf(KeyEvent.KEYCODE_MINUS),
                 KeyEvent.META_META_ON or KeyEvent.META_ALT_ON,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
             ),
             TestData(
-                "META + ALT + '=' -> Magnifier Zoom In",
+                "META + ALT + '=' -> Magnification Zoom In",
                 intArrayOf(
                     KeyEvent.KEYCODE_META_LEFT,
                     KeyEvent.KEYCODE_ALT_LEFT,
                     KeyEvent.KEYCODE_EQUALS
                 ),
-                KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_ZOOM_IN,
+                KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN,
                 intArrayOf(KeyEvent.KEYCODE_EQUALS),
                 KeyEvent.META_META_ON or KeyEvent.META_ALT_ON,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
@@ -785,49 +785,49 @@
             TestData(
                 "META + ALT + 'Down' -> Magnification Pan Down",
                 intArrayOf(
-                    KeyEvent.KEYCODE_CTRL_LEFT,
+                    KeyEvent.KEYCODE_META_LEFT,
                     KeyEvent.KEYCODE_ALT_LEFT,
                     KeyEvent.KEYCODE_DPAD_DOWN
                 ),
-                KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_DOWN,
+                KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN,
                 intArrayOf(KeyEvent.KEYCODE_DPAD_DOWN),
-                KeyEvent.META_CTRL_ON or KeyEvent.META_ALT_ON,
+                KeyEvent.META_META_ON or KeyEvent.META_ALT_ON,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
             ),
             TestData(
                 "META + ALT + 'Up' -> Magnification Pan Up",
                 intArrayOf(
-                    KeyEvent.KEYCODE_CTRL_LEFT,
+                    KeyEvent.KEYCODE_META_LEFT,
                     KeyEvent.KEYCODE_ALT_LEFT,
                     KeyEvent.KEYCODE_DPAD_UP
                 ),
-                KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_UP,
+                KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP,
                 intArrayOf(KeyEvent.KEYCODE_DPAD_UP),
-                KeyEvent.META_CTRL_ON or KeyEvent.META_ALT_ON,
+                KeyEvent.META_META_ON or KeyEvent.META_ALT_ON,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
             ),
             TestData(
                 "META + ALT + 'Left' -> Magnification Pan Left",
                 intArrayOf(
-                    KeyEvent.KEYCODE_CTRL_LEFT,
+                    KeyEvent.KEYCODE_META_LEFT,
                     KeyEvent.KEYCODE_ALT_LEFT,
                     KeyEvent.KEYCODE_DPAD_LEFT
                 ),
-                KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_LEFT,
+                KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT,
                 intArrayOf(KeyEvent.KEYCODE_DPAD_LEFT),
-                KeyEvent.META_CTRL_ON or KeyEvent.META_ALT_ON,
+                KeyEvent.META_META_ON or KeyEvent.META_ALT_ON,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
             ),
             TestData(
                 "META + ALT + 'Right' -> Magnification Pan Right",
                 intArrayOf(
-                    KeyEvent.KEYCODE_CTRL_LEFT,
+                    KeyEvent.KEYCODE_META_LEFT,
                     KeyEvent.KEYCODE_ALT_LEFT,
                     KeyEvent.KEYCODE_DPAD_RIGHT
                 ),
-                KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFIER_PAN_RIGHT,
+                KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT,
                 intArrayOf(KeyEvent.KEYCODE_DPAD_RIGHT),
-                KeyEvent.META_CTRL_ON or KeyEvent.META_ALT_ON,
+                KeyEvent.META_META_ON or KeyEvent.META_ALT_ON,
                 intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
             ),
         )
diff --git a/tests/Input/src/com/android/test/input/UinputRecordingIntegrationTests.kt b/tests/Input/src/com/android/test/input/UinputRecordingIntegrationTests.kt
index c61a250..0b281d8 100644
--- a/tests/Input/src/com/android/test/input/UinputRecordingIntegrationTests.kt
+++ b/tests/Input/src/com/android/test/input/UinputRecordingIntegrationTests.kt
@@ -21,6 +21,7 @@
 import android.graphics.PointF
 import android.hardware.input.InputManager
 import android.os.ParcelFileDescriptor
+import android.server.wm.CtsWindowInfoUtils.waitForWindowOnTop
 import android.util.Log
 import android.util.Size
 import android.view.InputEvent
@@ -113,6 +114,7 @@
             testName,
             size = testData.displaySize
         ).use { scenario ->
+            waitForWindowOnTop(scenario.activity.window)
             scenario.activity.window.decorView.requestUnbufferedDispatch(INPUT_DEVICE_SOURCE_ALL)
 
             try {